diff --git a/src/meta-srv/src/handler/node_stat.rs b/src/meta-srv/src/handler/node_stat.rs index f17d7a2d8ff7..609e806296d6 100644 --- a/src/meta-srv/src/handler/node_stat.rs +++ b/src/meta-srv/src/handler/node_stat.rs @@ -77,7 +77,7 @@ impl Stat { pub fn regions(&self) -> Vec<(RegionId, RegionRole)> { self.region_stats .iter() - .map(|s| (RegionId::from(s.id), s.role.into())) + .map(|s| (RegionId::from(s.id), s.role)) .collect() } diff --git a/src/meta-srv/src/handler/region_lease_handler.rs b/src/meta-srv/src/handler/region_lease_handler.rs index cae254cbc262..8b1f38614754 100644 --- a/src/meta-srv/src/handler/region_lease_handler.rs +++ b/src/meta-srv/src/handler/region_lease_handler.rs @@ -145,7 +145,7 @@ mod test { fn new_empty_region_stat(region_id: RegionId, role: RegionRole) -> RegionStat { RegionStat { id: region_id.as_u64(), - role: role.into(), + role, rcus: 0, wcus: 0, approximate_bytes: 0, @@ -209,10 +209,7 @@ mod test { handler.handle(&req, ctx, acc).await.unwrap(); - assert_region_lease( - &acc, - vec![GrantedRegion::new(region_id, RegionRole::Leader)], - ); + assert_region_lease(acc, vec![GrantedRegion::new(region_id, RegionRole::Leader)]); let acc = &mut HeartbeatAccumulator::default(); @@ -234,7 +231,7 @@ mod test { ); assert_region_lease( - &acc, + acc, vec![GrantedRegion::new(region_id, RegionRole::Follower)], ); } @@ -305,7 +302,7 @@ mod test { handler.handle(&req, ctx, acc).await.unwrap(); assert_region_lease( - &acc, + acc, vec![ GrantedRegion::new(region_id, RegionRole::Follower), GrantedRegion::new(another_region_id, RegionRole::Leader), diff --git a/src/meta-srv/src/inactive_region_manager.rs b/src/meta-srv/src/inactive_region_manager.rs deleted file mode 100644 index 273aad844b4d..000000000000 --- a/src/meta-srv/src/inactive_region_manager.rs +++ /dev/null @@ -1,156 +0,0 @@ -// Copyright 2023 Greptime Team -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -use std::collections::HashSet; - -use common_meta::kv_backend::ResettableKvBackendRef; -use common_meta::rpc::store::{BatchGetRequest, DeleteRangeRequest, PutRequest, RangeRequest}; -use common_meta::RegionIdent; -use snafu::ResultExt; - -use crate::error::{self, Result}; -use crate::keys::InactiveRegionKey; -use crate::metrics::METRIC_META_INACTIVE_REGIONS; - -pub struct InactiveRegionManager<'a> { - store: &'a ResettableKvBackendRef, -} - -impl<'a> InactiveRegionManager<'a> { - pub fn new(store: &'a ResettableKvBackendRef) -> Self { - Self { store } - } - - pub async fn register_inactive_region(&self, region_ident: &RegionIdent) -> Result<()> { - let region_id = region_ident.get_region_id().as_u64(); - let key = InactiveRegionKey { - cluster_id: region_ident.cluster_id, - node_id: region_ident.datanode_id, - region_id, - }; - let req = PutRequest { - key: key.into(), - value: vec![], - prev_kv: false, - }; - self.store.put(req).await.context(error::KvBackendSnafu)?; - - METRIC_META_INACTIVE_REGIONS.inc(); - - Ok(()) - } - - pub async fn deregister_inactive_region(&self, region_ident: &RegionIdent) -> Result<()> { - let region_id = region_ident.get_region_id().as_u64(); - let key: Vec = InactiveRegionKey { - cluster_id: region_ident.cluster_id, - node_id: region_ident.datanode_id, - region_id, - } - .into(); - self.store - .delete(&key, false) - .await - .context(error::KvBackendSnafu)?; - - METRIC_META_INACTIVE_REGIONS.dec(); - - Ok(()) - } - - /// The input is a list of regions on a specific node. If one or more regions have been - /// set to inactive state by metasrv, the corresponding regions will be removed(update the - /// `region_ids`), then returns the removed regions. - pub async fn retain_active_regions( - &self, - cluster_id: u64, - node_id: u64, - region_ids: &mut Vec, - ) -> Result> { - let key_region_ids = region_ids - .iter() - .map(|region_id| { - ( - InactiveRegionKey { - cluster_id, - node_id, - region_id: *region_id, - } - .into(), - *region_id, - ) - }) - .collect::, _)>>(); - let keys = key_region_ids.iter().map(|(key, _)| key.clone()).collect(); - let resp = self - .store - .batch_get(BatchGetRequest { keys }) - .await - .context(error::KvBackendSnafu)?; - let kvs = resp.kvs; - if kvs.is_empty() { - return Ok(HashSet::new()); - } - - let inactive_keys = kvs.into_iter().map(|kv| kv.key).collect::>(); - let (active_region_ids, inactive_region_ids): (Vec>, Vec>) = - key_region_ids - .into_iter() - .map(|(key, region_id)| { - let is_active = !inactive_keys.contains(&key); - if is_active { - (Some(region_id), None) - } else { - (None, Some(region_id)) - } - }) - .unzip(); - *region_ids = active_region_ids.into_iter().flatten().collect(); - - Ok(inactive_region_ids.into_iter().flatten().collect()) - } - - /// Scan all inactive regions in the cluster. - /// - /// When will these data appear? - /// Generally, it is because the corresponding Datanode is disconnected and - /// did not respond to the `Failover` scheduling instructions of metasrv. - pub async fn scan_all_inactive_regions( - &self, - cluster_id: u64, - ) -> Result> { - let prefix = InactiveRegionKey::get_prefix_by_cluster(cluster_id); - let request = RangeRequest::new().with_prefix(prefix); - let resp = self - .store - .range(request) - .await - .context(error::KvBackendSnafu)?; - let kvs = resp.kvs; - kvs.into_iter() - .map(|kv| InactiveRegionKey::try_from(kv.key)) - .collect::>>() - } - - pub async fn clear_all_inactive_regions(&self, cluster_id: u64) -> Result<()> { - let prefix = InactiveRegionKey::get_prefix_by_cluster(cluster_id); - let request = DeleteRangeRequest::new().with_prefix(prefix); - let _ = self - .store - .delete_range(request) - .await - .context(error::KvBackendSnafu)?; - Ok(()) - } -} diff --git a/src/meta-srv/src/lib.rs b/src/meta-srv/src/lib.rs index 14af05f8c0c5..b30c6779b36a 100644 --- a/src/meta-srv/src/lib.rs +++ b/src/meta-srv/src/lib.rs @@ -40,8 +40,6 @@ pub mod table_meta_alloc; pub use crate::error::Result; -mod inactive_region_manager; - mod greptimedb_telemetry; #[cfg(test)] diff --git a/src/meta-srv/src/procedure/region_failover/activate_region.rs b/src/meta-srv/src/procedure/region_failover/activate_region.rs index 69dc51334358..9a7fb13a317f 100644 --- a/src/meta-srv/src/procedure/region_failover/activate_region.rs +++ b/src/meta-srv/src/procedure/region_failover/activate_region.rs @@ -31,7 +31,6 @@ use crate::error::{ self, Error, Result, RetryLaterSnafu, SerializeToJsonSnafu, UnexpectedInstructionReplySnafu, }; use crate::handler::HeartbeatMailbox; -use crate::inactive_region_manager::InactiveRegionManager; use crate::procedure::region_failover::OPEN_REGION_MESSAGE_TIMEOUT; use crate::service::mailbox::{Channel, MailboxReceiver}; @@ -104,17 +103,6 @@ impl ActivateRegion { input: instruction.to_string(), })?; - // Ensure that metasrv will renew the lease for this candidate node. - // - // This operation may not be redundant, imagine the following scenario: - // This candidate once had the current region, and because it did not respond to the `close` - // command in time, it was considered an inactive node by metasrv, then it replied, and the - // current region failed over again, and the node was selected as a candidate, so it needs - // to clear its previous state first. - InactiveRegionManager::new(&ctx.in_memory) - .deregister_inactive_region(&candidate_ident) - .await?; - let ch = Channel::Datanode(self.candidate.id); ctx.mailbox.send(&ch, msg, timeout).await } @@ -182,13 +170,6 @@ impl State for ActivateRegion { ctx: &RegionFailoverContext, failed_region: &RegionIdent, ) -> Result> { - if self.remark_inactive_region { - // Remark the fail region as inactive to prevent it from renewing the lease. - InactiveRegionManager::new(&ctx.in_memory) - .register_inactive_region(failed_region) - .await?; - } - let mailbox_receiver = self .send_open_region_message(ctx, failed_region, OPEN_REGION_MESSAGE_TIMEOUT) .await?; diff --git a/src/meta-srv/src/procedure/region_failover/deactivate_region.rs b/src/meta-srv/src/procedure/region_failover/deactivate_region.rs index d24ae9f68b8c..04b3ccde97e4 100644 --- a/src/meta-srv/src/procedure/region_failover/deactivate_region.rs +++ b/src/meta-srv/src/procedure/region_failover/deactivate_region.rs @@ -30,7 +30,6 @@ use crate::error::{ self, Error, Result, RetryLaterSnafu, SerializeToJsonSnafu, UnexpectedInstructionReplySnafu, }; use crate::handler::HeartbeatMailbox; -use crate::inactive_region_manager::InactiveRegionManager; use crate::service::mailbox::{Channel, MailboxReceiver}; #[derive(Serialize, Deserialize, Debug)] @@ -91,22 +90,13 @@ impl DeactivateRegion { })?; let ch = Channel::Datanode(failed_region.datanode_id); - // Mark the region as inactive - InactiveRegionManager::new(&ctx.in_memory) - .register_inactive_region(failed_region) - .await?; - // We first marked the region as inactive, which means that the failed region cannot - // be successfully renewed from now on, so after the lease time is exceeded, the region - // will be automatically closed. - // If the deadline is exceeded, we can proceed to the next step with confidence, - // as the expiration means that the region has been closed. let timeout = Duration::from_secs(ctx.region_lease_secs); ctx.mailbox.send(&ch, msg, timeout).await } async fn handle_response( &self, - ctx: &RegionFailoverContext, + _ctx: &RegionFailoverContext, mailbox_receiver: MailboxReceiver, failed_region: &RegionIdent, ) -> Result> { @@ -123,10 +113,6 @@ impl DeactivateRegion { .fail(); }; if result { - InactiveRegionManager::new(&ctx.in_memory) - .deregister_inactive_region(failed_region) - .await?; - Ok(Box::new(ActivateRegion::new(self.candidate.clone()))) } else { // Under rare circumstances would a Datanode fail to close a Region. diff --git a/src/meta-srv/src/service/admin.rs b/src/meta-srv/src/service/admin.rs index c7eac3af4231..a5867e376924 100644 --- a/src/meta-srv/src/service/admin.rs +++ b/src/meta-srv/src/service/admin.rs @@ -14,7 +14,6 @@ mod health; mod heartbeat; -mod inactive_regions; mod leader; mod meta; mod node_lease; @@ -91,20 +90,6 @@ pub fn make_admin_service(meta_srv: MetaSrv) -> Admin { .route("/route", handler.clone()) .route("/route/help", handler); - let router = router.route( - "/inactive-regions/view", - inactive_regions::ViewInactiveRegionsHandler { - store: meta_srv.in_memory().clone(), - }, - ); - - let router = router.route( - "/inactive-regions/clear", - inactive_regions::ClearInactiveRegionsHandler { - store: meta_srv.in_memory().clone(), - }, - ); - let router = Router::nest("/admin", router); Admin::new(router) diff --git a/src/meta-srv/src/service/admin/inactive_regions.rs b/src/meta-srv/src/service/admin/inactive_regions.rs deleted file mode 100644 index 6c3c4184903e..000000000000 --- a/src/meta-srv/src/service/admin/inactive_regions.rs +++ /dev/null @@ -1,92 +0,0 @@ -// Copyright 2023 Greptime Team -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -use std::collections::HashMap; - -use common_meta::kv_backend::ResettableKvBackendRef; -use serde::{Deserialize, Serialize}; -use snafu::ResultExt; -use tonic::codegen::http; - -use crate::error::{self, Result}; -use crate::inactive_region_manager::InactiveRegionManager; -use crate::keys::InactiveRegionKey; -use crate::service::admin::{util, HttpHandler}; - -pub struct ViewInactiveRegionsHandler { - pub store: ResettableKvBackendRef, -} - -#[async_trait::async_trait] -impl HttpHandler for ViewInactiveRegionsHandler { - async fn handle( - &self, - _: &str, - params: &HashMap, - ) -> Result> { - let cluster_id = util::extract_cluster_id(params)?; - - let inactive_region_manager = InactiveRegionManager::new(&self.store); - let inactive_regions = inactive_region_manager - .scan_all_inactive_regions(cluster_id) - .await?; - let result = InactiveRegions { inactive_regions }.try_into()?; - - http::Response::builder() - .status(http::StatusCode::OK) - .body(result) - .context(error::InvalidHttpBodySnafu) - } -} - -pub struct ClearInactiveRegionsHandler { - pub store: ResettableKvBackendRef, -} - -#[async_trait::async_trait] -impl HttpHandler for ClearInactiveRegionsHandler { - async fn handle( - &self, - _: &str, - params: &HashMap, - ) -> Result> { - let cluster_id = util::extract_cluster_id(params)?; - - let inactive_region_manager = InactiveRegionManager::new(&self.store); - inactive_region_manager - .clear_all_inactive_regions(cluster_id) - .await?; - - Ok(http::Response::builder() - .status(http::StatusCode::OK) - .body("Success\n".to_owned()) - .unwrap()) - } -} - -#[derive(Debug, Serialize, Deserialize)] -#[serde(transparent)] -struct InactiveRegions { - inactive_regions: Vec, -} - -impl TryFrom for String { - type Error = error::Error; - - fn try_from(value: InactiveRegions) -> Result { - serde_json::to_string(&value).context(error::SerializeToJsonSnafu { - input: format!("{value:?}"), - }) - } -}