[LogService] Support the ls delay GC
This commit is contained in:
		| @ -15,6 +15,7 @@ | ||||
| #include "ob_log_handler.h" | ||||
| #include "ob_log_service.h" | ||||
| #include "ob_switch_leader_adapter.h" | ||||
| #include "common_util/ob_log_time_utils.h" | ||||
| #include "archiveservice/ob_archive_service.h" | ||||
| #include "share/scn.h" | ||||
| #include "rpc/obrpc/ob_rpc_net_handler.h" | ||||
| @ -617,11 +618,10 @@ void ObGCHandler::try_check_and_set_wait_gc_(ObGarbageCollector::LSStatus &ls_st | ||||
|   } else if (OB_FAIL(check_if_tenant_in_archive_(tenant_in_archive))) { | ||||
|     CLOG_LOG(WARN, "check_if_tenant_in_archive_ failed", K(ret), K(ls_id), K(gc_state)); | ||||
|   } else if (! tenant_in_archive) { | ||||
|     if (OB_FAIL(ls_->set_gc_state(LSGCState::WAIT_GC))) { | ||||
|       CLOG_LOG(WARN, "set_gc_state failed", K(ls_id), K(gc_state), K(ret)); | ||||
|     if (OB_FAIL(try_check_and_set_wait_gc_when_log_archive_is_off_(gc_state, readable_scn, offline_scn, ls_status))) { | ||||
|       CLOG_LOG(WARN, "try_check_and_set_wait_gc_when_log_archive_is_off_ failed", K(ret), K(ls_id), K(gc_state), | ||||
|           K(readable_scn), K(offline_scn), K(ls_status)); | ||||
|     } | ||||
|     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(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) { | ||||
| @ -641,6 +641,96 @@ void ObGCHandler::try_check_and_set_wait_gc_(ObGarbageCollector::LSStatus &ls_st | ||||
|   } | ||||
| } | ||||
|  | ||||
| int ObGCHandler::try_check_and_set_wait_gc_when_log_archive_is_off_( | ||||
|     const LSGCState &gc_state, | ||||
|     const share::SCN &readable_scn, | ||||
|     const share::SCN &offline_scn, | ||||
|     ObGarbageCollector::LSStatus &ls_status) | ||||
| { | ||||
|   int ret = OB_SUCCESS; | ||||
|  | ||||
|   if (OB_ISNULL(ls_)) { | ||||
|     ret = OB_ERR_UNEXPECTED; | ||||
|     CLOG_LOG(WARN, "ls_ is nullptr", KR(ret)); | ||||
|   } else { | ||||
|     const uint64_t tenant_id = MTL_ID(); | ||||
|     int tmp_ret = OB_SUCCESS; | ||||
|     bool is_tenant_dropping_or_dropped = false; | ||||
|  | ||||
|     if (OB_SUCCESS != (tmp_ret = check_if_tenant_is_dropping_or_dropped_(tenant_id, is_tenant_dropping_or_dropped))) { | ||||
|       CLOG_LOG(WARN, "check_if_tenant_has_been_dropped_ failed", K(tmp_ret), K(tenant_id), K(ls_id)); | ||||
|     } else if (is_tenant_dropping_or_dropped) { | ||||
|       // The LS delay deletion mechanism will no longer take effect when the tenant is dropped. | ||||
|       if (OB_FAIL(ls_->set_gc_state(LSGCState::WAIT_GC))) { | ||||
|         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, "Tenant is dropped and the log stream can be removed, try_check_and_set_wait_gc_ success", | ||||
|           K(tenant_id), K(ls_id), K(gc_state), K(offline_scn), K(readable_scn)); | ||||
|     } else { | ||||
|       omt::ObTenantConfigGuard tenant_config(TENANT_CONF(tenant_id)); | ||||
|       // The LS delay deletion mechanism will take effect when the tenant is not dropped. | ||||
|       if (! tenant_config.is_valid()) { | ||||
|         ret = OB_INVALID_ARGUMENT; | ||||
|         CLOG_LOG(WARN, "tenant_config is not valid", K(ret), K(tenant_id)); | ||||
|       } else if (OB_UNLIKELY(OB_INVALID_TIMESTAMP == gc_start_ts_)) { | ||||
|         ret = OB_INVALID_ARGUMENT; | ||||
|         CLOG_LOG(WARN, "gc_start_ts_ is not valid", KR(ret), K(ls_), K(gc_start_ts_)); | ||||
|       } else { | ||||
|         const int64_t ls_gc_delay_time = tenant_config->ls_gc_delay_time; | ||||
|         const int64_t current_time_us = common::ObTimeUtility::current_time(); | ||||
|  | ||||
|         if ((current_time_us - gc_start_ts_) >= ls_gc_delay_time) { | ||||
|           if (OB_FAIL(ls_->set_gc_state(LSGCState::WAIT_GC))) { | ||||
|             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, "The log stream can be removed, try_check_and_set_wait_gc_ success", | ||||
|               K(ls_id), K(gc_state), K(offline_scn), K(readable_scn), K(ls_gc_delay_time)); | ||||
|         } else { | ||||
|           CLOG_LOG(INFO, "The log stream requires delayed gc", K(ls_id), | ||||
|               K(ls_gc_delay_time), K(gc_start_ts_), | ||||
|               "gc_start_ts", TS_TO_STR(gc_start_ts_), | ||||
|               "current_time", TS_TO_STR(current_time_us)); | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   return ret; | ||||
| } | ||||
|  | ||||
| int ObGCHandler::check_if_tenant_is_dropping_or_dropped_(const uint64_t tenant_id, | ||||
|     bool &is_tenant_dropping_or_dropped) | ||||
| { | ||||
|   int ret = OB_SUCCESS; | ||||
|   schema::ObMultiVersionSchemaService *schema_service = GCTX.schema_service_; | ||||
|   schema::ObSchemaGetterGuard guard; | ||||
|   is_tenant_dropping_or_dropped = false; | ||||
|   const ObTenantSchema *tenant_schema = nullptr; | ||||
|  | ||||
|   if (OB_ISNULL(schema_service)) { | ||||
|     ret = OB_ERR_UNEXPECTED; | ||||
|     CLOG_LOG(WARN, "schema_service is nullptr", KR(ret)); | ||||
|   } else if (OB_FAIL(schema_service->get_tenant_schema_guard(OB_SYS_TENANT_ID, guard))) { | ||||
|     CLOG_LOG(WARN, "fail to get schema guard", KR(ret), K(tenant_id)); | ||||
|   } else if (OB_FAIL(guard.get_tenant_info(tenant_id, tenant_schema))) { | ||||
|     CLOG_LOG(WARN, "get tenant info failed", KR(ret), K(tenant_id)); | ||||
|   } else if (OB_ISNULL(tenant_schema)) { | ||||
|     // Double check the tenant status to avoid any potential problems in the schema module. | ||||
|     if (OB_FAIL(guard.check_if_tenant_has_been_dropped(tenant_id, is_tenant_dropping_or_dropped))) { | ||||
|       CLOG_LOG(WARN, "fail to check if tenant has been dropped", KR(ret), K(tenant_id)); | ||||
|     } else { | ||||
|       CLOG_LOG(INFO, "tenant info is nullptr, check the tenant status", | ||||
|           K(tenant_id), K(is_tenant_dropping_or_dropped)); | ||||
|     } | ||||
|   } else { | ||||
|     is_tenant_dropping_or_dropped = tenant_schema->is_dropping(); | ||||
|   } | ||||
|  | ||||
|   return ret; | ||||
| } | ||||
|  | ||||
| int ObGCHandler::get_tenant_readable_scn_(SCN &readable_scn) | ||||
| { | ||||
|   int ret = OB_SUCCESS; | ||||
| @ -817,7 +907,11 @@ void ObGCHandler::handle_gc_ls_dropping_(const ObGarbageCollector::LSStatus &ls_ | ||||
|     ObRole role; | ||||
|     ObLSID ls_id = ls_->get_ls_id(); | ||||
|     LSGCState gc_state = INVALID_LS_GC_STATE; | ||||
|     gc_start_ts_ = ObTimeUtility::current_time(); | ||||
|     // If gc_start_ts_ is an invalid value, it is necessary to get the current time again to avoid a situation | ||||
|     // where gc_start_ts_ remains an invalid value after ObServer restart, which may affect the GC logic. | ||||
|     if (OB_INVALID_TIMESTAMP == gc_start_ts_) { | ||||
|       gc_start_ts_ = ObTimeUtility::current_time(); | ||||
|     } | ||||
|     if (OB_FAIL(get_palf_role_(role))) { | ||||
|       CLOG_LOG(WARN, "get_palf_role_ failed", K(ls_id)); | ||||
|     } else if (ObRole::LEADER != role) { | ||||
| @ -849,6 +943,12 @@ void ObGCHandler::handle_gc_ls_offline_(ObGarbageCollector::LSStatus &ls_status) | ||||
|     ObRole role; | ||||
|     ObLSID ls_id = ls_->get_ls_id(); | ||||
|     LSGCState gc_state = INVALID_LS_GC_STATE; | ||||
|     // If gc_start_ts_ is an invalid value, it is necessary to get the current time again to avoid a situation | ||||
|     // where gc_start_ts_ remains an invalid value after ObServer restart, which may affect the GC logic. | ||||
|     if (OB_INVALID_TIMESTAMP == gc_start_ts_) { | ||||
|       gc_start_ts_ = ObTimeUtility::current_time(); | ||||
|     } | ||||
|  | ||||
|     if (OB_FAIL(get_palf_role_(role))) { | ||||
|       CLOG_LOG(WARN, "get_palf_role_ failed", K(ls_id)); | ||||
|     } else if (ObRole::LEADER != role) { | ||||
|  | ||||
		Reference in New Issue
	
	Block a user
	 obdev
					obdev