diff --git a/src/storage/ls/ob_ls.cpp b/src/storage/ls/ob_ls.cpp index c890a8fe67..453e3ddebb 100644 --- a/src/storage/ls/ob_ls.cpp +++ b/src/storage/ls/ob_ls.cpp @@ -698,6 +698,7 @@ int ObLS::offline_() LOG_WARN("lock table offline failed", K(ret), K(ls_meta_)); } else if (OB_FAIL(ls_tablet_svr_.offline())) { LOG_WARN("tablet service offline failed", K(ret), K(ls_meta_)); + } else if (FALSE_IT(tablet_gc_handler_.offline())) { } else { // do nothing } @@ -766,7 +767,7 @@ int ObLS::online() } else if (OB_FAIL(online_compaction_())) { LOG_WARN("compaction online failed", K(ret), K(ls_meta_)); } else if (FALSE_IT(checkpoint_executor_.online())) { - LOG_WARN("checkpoint executor online failed", K(ret), K(ls_meta_)); + } else if (FALSE_IT(tablet_gc_handler_.online())) { } else { is_offlined_ = false; // do nothing diff --git a/src/storage/tx_storage/ob_tablet_gc_service.cpp b/src/storage/tx_storage/ob_tablet_gc_service.cpp index 98196ed30c..4cab9a7af6 100644 --- a/src/storage/tx_storage/ob_tablet_gc_service.cpp +++ b/src/storage/tx_storage/ob_tablet_gc_service.cpp @@ -124,16 +124,19 @@ void ObTabletGCService::ObTabletGCTask::runTimerTask() ObLS *ls = NULL; int ls_cnt = 0; for (; OB_SUCC(ret) && OB_SUCC(iter->get_next(ls)); ++ls_cnt) { - ObTabletGCHandler *tablet_gc_handler = ls->get_tablet_gc_handler(); + 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()) { } else { uint8_t tablet_persist_trigger = tablet_gc_handler->get_tablet_persist_trigger_and_reset(); STORAGE_LOG(INFO, "[tabletgc] 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)) { + obsys::ObWLockGuard lock(tablet_gc_handler->wait_lock_); bool need_retry = false; int64_t checkpoint_ts = INT64_MAX; ObFreezer *freezer = ls->get_freezer(); @@ -141,6 +144,7 @@ void ObTabletGCService::ObTabletGCTask::runTimerTask() common::ObTabletIDArray deleted_tablet_ids; const bool is_deleted = true; const bool only_deleted = true; + if (OB_ISNULL(freezer)) { ret = OB_ERR_UNEXPECTED; STORAGE_LOG(WARN, "freezer should not null", K(ls->get_ls_id()), KR(ret)); @@ -278,7 +282,10 @@ int ObTabletGCHandler::get_unpersist_tablet_ids(common::ObTabletIDArray &unpersi ObTabletHandle tablet_handle; while (OB_SUCC(ret)) { tx_data.reset(); - if (OB_FAIL(tablet_iter.get_next_tablet(tablet_handle))) { + 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())); + } else if (OB_FAIL(tablet_iter.get_next_tablet(tablet_handle))) { if (OB_ITER_END == ret) { ret = OB_SUCCESS; break; @@ -365,6 +372,9 @@ int ObTabletGCHandler::wait_unpersist_tablet_ids_flushed(const common::ObTabletI if (IS_NOT_INIT) { ret = OB_NOT_INIT; STORAGE_LOG(WARN, "tablet gc handle 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())); } // wait all tablet flushed while (unpersist_tablet_ids.count() > i && retry_times > 0 && OB_SUCC(ret)) { @@ -373,7 +383,10 @@ int ObTabletGCHandler::wait_unpersist_tablet_ids_flushed(const common::ObTabletI ObTabletHandle handle; ObTablet *tablet = nullptr; int64_t rec_log_ts = 0; - if (OB_FAIL(ls_->get_tablet_svr()->get_tablet(unpersist_tablet_ids.at(i), handle, ObTabletCommon::NO_CHECK_GET_TABLET_TIMEOUT_US))) { + 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))) { 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; @@ -411,6 +424,9 @@ int ObTabletGCHandler::gc_tablets(const common::ObTabletIDArray &tablet_ids) 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(ls_->get_tablet_svr()->remove_tablets(tablet_ids))) { STORAGE_LOG(WARN, "[tabletgc] failed to remove tablets", K(ret), K(tablet_ids)); } else { @@ -419,6 +435,21 @@ int ObTabletGCHandler::gc_tablets(const common::ObTabletIDArray &tablet_ids) return ret; } +void ObTabletGCHandler::offline() +{ + set_stop(); + wait_stop(); + STORAGE_LOG(INFO, "tablet gc handler offline", KPC(this), KPC(ls_), K(ls_->get_ls_meta())); +} + +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())); +} + } // checkpoint } // storage } // oceanbase diff --git a/src/storage/tx_storage/ob_tablet_gc_service.h b/src/storage/tx_storage/ob_tablet_gc_service.h index 616b2e4cf9..8485f040ea 100644 --- a/src/storage/tx_storage/ob_tablet_gc_service.h +++ b/src/storage/tx_storage/ob_tablet_gc_service.h @@ -13,8 +13,8 @@ #ifndef OCEABASE_STORAGE_OB_TABLET_GC_SERVICE_ #define OCEABASE_STORAGE_OB_TABLET_GC_SERVICE_ #include "storage/tx_storage/ob_ls_freeze_thread.h" -#include "lib/lock/ob_spin_lock.h" #include "lib/task/ob_timer.h" +#include "lib/lock/ob_rwlock.h" #include "common/ob_tablet_id.h" namespace oceanbase @@ -31,6 +31,7 @@ public: ObTabletGCHandler() : ls_(NULL), tablet_persist_trigger_(0), + update_enabled_(true), is_inited_(false) {} ~ObTabletGCHandler() { reset(); } @@ -56,6 +57,9 @@ public: int flush_unpersist_tablet_ids(const common::ObTabletIDArray &unpersist_tablet_ids, const int64_t checkpoint_ts); int gc_tablets(const common::ObTabletIDArray &tablet_ids); + bool check_stop() { return ATOMIC_LOAD(&update_enabled_) == false; } + void offline(); + void online(); TO_STRING_KV(K_(tablet_persist_trigger), K_(is_inited)); private: @@ -64,10 +68,17 @@ private: int freeze_unpersist_tablet_ids(const common::ObTabletIDArray &unpersist_tablet_ids); int wait_unpersist_tablet_ids_flushed(const common::ObTabletIDArray &unpersist_tablet_ids, const int64_t checkpoint_ts); + void wait_stop() { obsys::ObWLockGuard lock(wait_lock_); } + void set_stop() { ATOMIC_STORE(&update_enabled_, false); } + void set_start() { ATOMIC_STORE(&update_enabled_, true); } + +public: + obsys::ObRWLock wait_lock_; private: storage::ObLS *ls_; uint8_t tablet_persist_trigger_; + bool update_enabled_; bool is_inited_; };