mirror of
https://github.com/GreptimeTeam/greptimedb.git
synced 2026-01-04 20:32:56 +00:00
fix: refactor region leader state validation (#5626)
* enhance: refactor region leader state validation * chore: apply suggestions from CR * chore: add logs
This commit is contained in:
@@ -490,6 +490,18 @@ pub enum Error {
|
||||
location: Location,
|
||||
},
|
||||
|
||||
#[snafu(display(
|
||||
"Region {} is in {:?} state, which does not permit manifest updates.",
|
||||
region_id,
|
||||
state
|
||||
))]
|
||||
UpdateManifest {
|
||||
region_id: RegionId,
|
||||
state: RegionRoleState,
|
||||
#[snafu(implicit)]
|
||||
location: Location,
|
||||
},
|
||||
|
||||
#[snafu(display("Region {} is in {:?} state, expect: {:?}", region_id, state, expect))]
|
||||
RegionLeaderState {
|
||||
region_id: RegionId,
|
||||
@@ -1055,7 +1067,7 @@ impl ErrorExt for Error {
|
||||
CompactRegion { source, .. } => source.status_code(),
|
||||
CompatReader { .. } => StatusCode::Unexpected,
|
||||
InvalidRegionRequest { source, .. } => source.status_code(),
|
||||
RegionLeaderState { .. } => StatusCode::RegionNotReady,
|
||||
RegionLeaderState { .. } | UpdateManifest { .. } => StatusCode::RegionNotReady,
|
||||
&FlushableRegionState { .. } => StatusCode::RegionNotReady,
|
||||
JsonOptions { .. } => StatusCode::InvalidArguments,
|
||||
EmptyRegionDir { .. } | EmptyManifestDir { .. } => StatusCode::RegionNotFound,
|
||||
|
||||
@@ -36,7 +36,7 @@ use store_api::storage::RegionId;
|
||||
use crate::access_layer::AccessLayerRef;
|
||||
use crate::error::{
|
||||
FlushableRegionStateSnafu, RegionLeaderStateSnafu, RegionNotFoundSnafu, RegionTruncatedSnafu,
|
||||
Result,
|
||||
Result, UpdateManifestSnafu,
|
||||
};
|
||||
use crate::manifest::action::{RegionMetaAction, RegionMetaActionList};
|
||||
use crate::manifest::manager::RegionManifestManager;
|
||||
@@ -371,14 +371,36 @@ impl ManifestContext {
|
||||
// Checks state inside the lock. This is to ensure that we won't update the manifest
|
||||
// after `set_readonly_gracefully()` is called.
|
||||
let current_state = self.state.load();
|
||||
ensure!(
|
||||
current_state == RegionRoleState::Leader(expect_state),
|
||||
RegionLeaderStateSnafu {
|
||||
region_id: manifest.metadata.region_id,
|
||||
state: current_state,
|
||||
expect: expect_state,
|
||||
|
||||
// If expect_state is not downgrading, the current state must be either `expect_state` or downgrading.
|
||||
//
|
||||
// A downgrading leader rejects user writes but still allows
|
||||
// flushing the memtable and updating the manifest.
|
||||
if expect_state != RegionLeaderState::Downgrading {
|
||||
if current_state == RegionRoleState::Leader(RegionLeaderState::Downgrading) {
|
||||
info!(
|
||||
"Region {} is in downgrading leader state, updating manifest. state is {:?}",
|
||||
manifest.metadata.region_id, expect_state
|
||||
);
|
||||
}
|
||||
);
|
||||
ensure!(
|
||||
current_state == RegionRoleState::Leader(expect_state)
|
||||
|| current_state == RegionRoleState::Leader(RegionLeaderState::Downgrading),
|
||||
UpdateManifestSnafu {
|
||||
region_id: manifest.metadata.region_id,
|
||||
state: current_state,
|
||||
}
|
||||
);
|
||||
} else {
|
||||
ensure!(
|
||||
current_state == RegionRoleState::Leader(expect_state),
|
||||
RegionLeaderStateSnafu {
|
||||
region_id: manifest.metadata.region_id,
|
||||
state: current_state,
|
||||
expect: expect_state,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
for action in &action_list.actions {
|
||||
// Checks whether the edit is still applicable.
|
||||
|
||||
Reference in New Issue
Block a user