mirror of
https://github.com/rustfs/rustfs.git
synced 2026-08-26 05:56:50 +00:00
fix(scanner): fence system metadata publication (#6444)
* feat(scanner): fence usage publication during data movement * fix(scanner): detect movement refresh state changes * fix(scanner): fence publication during data movement * fix(scanner): close movement epoch publication races * fix(scanner): fence movement-sensitive publication paths * fix(scanner): fence cache and heal recovery paths * fix(scanner): carry publication epoch through scan cycle * fix(scanner): recheck remote cache epoch after save * fix(scanner): recheck local cache epoch before publish * fix(scanner): fence data usage writers and baseline * fix(scanner): expose decommission activity to publication fence * fix(scanner): release publication gate before reads * fix(scanner): complete publication fence integration * fix(scanner): avoid empty usage baseline publication * chore(scanner): gate test-only helpers * fix: use decommission canceler in reload test --------- Co-authored-by: houseme <housemecn@gmail.com>
This commit is contained in:
@@ -23,6 +23,7 @@ use crate::storage_api::owner::NS_SCANNER_PROTOCOL_VERSION;
|
||||
use crate::{
|
||||
DATA_USAGE_CACHE_NAME, DataUsageCache, DataUsageCachePrepareOutcome, DataUsageCacheSource, DataUsageEntryInfo,
|
||||
DataUsageScanPlanDigest, Disk, ScannerError, StorageError, resolve_scanner_object_store_handle,
|
||||
scanner_publication_admission_for_epoch, scanner_publication_epoch,
|
||||
};
|
||||
use hmac::{Hmac, KeyInit, Mac};
|
||||
use rustfs_common::heal_channel::HealScanMode;
|
||||
@@ -686,6 +687,9 @@ async fn scan_and_persist_local_bucket(
|
||||
source.pool_index, source.set_index
|
||||
))
|
||||
})?;
|
||||
let expected_publication_epoch = scanner_publication_epoch(set.clone()).await.ok_or_else(|| {
|
||||
RemoteScannerServerError::worker("remote namespace scanner cache publication is blocked by data movement")
|
||||
})?;
|
||||
let cache_name = path_join_buf(&[&bucket, DATA_USAGE_CACHE_NAME]);
|
||||
let guard = acquire_scanner_cache_locks(set.as_ref(), &cache_name, source)
|
||||
.await
|
||||
@@ -708,6 +712,14 @@ async fn scan_and_persist_local_bucket(
|
||||
"remote namespace scanner cache lock was lost before reusing the current snapshot",
|
||||
));
|
||||
}
|
||||
if scanner_publication_admission_for_epoch(set.clone(), expected_publication_epoch)
|
||||
.await
|
||||
.is_none()
|
||||
{
|
||||
return Err(RemoteScannerServerError::retry_bucket(
|
||||
"remote namespace scanner cache publication epoch changed before reusing the current snapshot",
|
||||
));
|
||||
}
|
||||
return Ok(RemoteScannerFrameResult::Complete(Box::new(RemoteScannerComplete {
|
||||
source,
|
||||
scan_plan_digest,
|
||||
@@ -796,9 +808,22 @@ async fn scan_and_persist_local_bucket(
|
||||
.await
|
||||
.map_err(|err| RemoteScannerServerError::worker(format!("remote namespace scanner leader fence changed: {err}")))?;
|
||||
let done_save = Metrics::time(Metric::SaveUsage);
|
||||
let save_result = cache.save_with_revisions(set, &cache_name, &revisions).await;
|
||||
// Each physical main/backup PUT must still prove the epoch captured before
|
||||
// the scan. A movement transition that starts and ends during the scan
|
||||
// therefore cannot admit the stale cache under the new epoch.
|
||||
let save_result = cache
|
||||
.save_with_revisions_for_epoch(set.clone(), &cache_name, &revisions, expected_publication_epoch)
|
||||
.await;
|
||||
done_save();
|
||||
save_result.map_err(|err| RemoteScannerServerError::worker(format!("remote namespace scanner cache save failed: {err}")))?;
|
||||
if scanner_publication_admission_for_epoch(set, expected_publication_epoch)
|
||||
.await
|
||||
.is_none()
|
||||
{
|
||||
return Err(RemoteScannerServerError::retry_bucket(
|
||||
"remote namespace scanner cache publication epoch changed after persistence",
|
||||
));
|
||||
}
|
||||
validate_remote_scanner_request_fence_with_store(next_cycle, leader_epoch, store)
|
||||
.await
|
||||
.map_err(|err| RemoteScannerServerError::worker(format!("remote namespace scanner leader fence changed: {err}")))?;
|
||||
|
||||
Reference in New Issue
Block a user