mirror of
https://github.com/rustfs/rustfs.git
synced 2026-08-22 20:36:38 +00:00
fix(scanner): scope cache locks by set
Co-Authored-By: heihutu <heihutu@gmail.com>
This commit is contained in:
@@ -951,7 +951,7 @@ async fn scan_and_persist_local_bucket(
|
|||||||
))
|
))
|
||||||
})?;
|
})?;
|
||||||
let cache_name = path_join_buf(&[&bucket, DATA_USAGE_CACHE_NAME]);
|
let cache_name = path_join_buf(&[&bucket, DATA_USAGE_CACHE_NAME]);
|
||||||
let lock_resource = scanner_cache_lock_resource(&cache_name);
|
let lock_resource = scanner_cache_lock_resource(&cache_name, source);
|
||||||
let ns_lock = set
|
let ns_lock = set
|
||||||
.new_ns_lock(RUSTFS_META_BUCKET, &lock_resource)
|
.new_ns_lock(RUSTFS_META_BUCKET, &lock_resource)
|
||||||
.await
|
.await
|
||||||
|
|||||||
@@ -944,8 +944,9 @@ fn checked_bucket_usage_info(entry: &DataUsageEntry) -> Option<BucketUsageInfo>
|
|||||||
Some(usage)
|
Some(usage)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn scanner_cache_lock_resource(cache_name: &str) -> String {
|
pub(crate) fn scanner_cache_lock_resource(cache_name: &str, source: DataUsageCacheSource) -> String {
|
||||||
path_join_buf(&[crate::BUCKET_META_PREFIX, cache_name, SCANNER_CACHE_LOCK_SUFFIX])
|
let lock_name = format!("{SCANNER_CACHE_LOCK_SUFFIX}.pool-{}.set-{}", source.pool_index, source.set_index);
|
||||||
|
path_join_buf(&[crate::BUCKET_META_PREFIX, cache_name, &lock_name])
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn scanner_cache_lock_timeout() -> Duration {
|
pub(crate) fn scanner_cache_lock_timeout() -> Duration {
|
||||||
@@ -1697,6 +1698,19 @@ mod publish_gate_tests {
|
|||||||
assert!(!cache_snapshot_is_current(&cache, "photos", source, 11, 0, second));
|
assert!(!cache_snapshot_is_current(&cache, "photos", source, 11, 0, second));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn scanner_cache_lock_resource_is_scoped_to_cache_source() {
|
||||||
|
let cache_name = "photos/.usage-cache.bin";
|
||||||
|
let first_source = DataUsageCacheSource::new(0, 1);
|
||||||
|
let same_source = DataUsageCacheSource::new(0, 1);
|
||||||
|
let other_source = DataUsageCacheSource::new(1, 0);
|
||||||
|
|
||||||
|
let first = scanner_cache_lock_resource(cache_name, first_source);
|
||||||
|
assert_eq!(first, scanner_cache_lock_resource(cache_name, same_source));
|
||||||
|
assert_ne!(first, scanner_cache_lock_resource(cache_name, other_source));
|
||||||
|
assert!(first.ends_with(".scanner-cycle.lock.pool-0.set-1"));
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn count_budget_serializes_set_and_disk_work() {
|
fn count_budget_serializes_set_and_disk_work() {
|
||||||
assert_eq!(scanner_budgeted_concurrency_limit(8, true), 1);
|
assert_eq!(scanner_budgeted_concurrency_limit(8, true), 1);
|
||||||
@@ -1797,7 +1811,7 @@ async fn persist_and_publish_cache_snapshot(
|
|||||||
cache_cycle_floor: &AtomicU64,
|
cache_cycle_floor: &AtomicU64,
|
||||||
) -> Option<SystemTime> {
|
) -> Option<SystemTime> {
|
||||||
let source = cache_snapshot.info.source?;
|
let source = cache_snapshot.info.source?;
|
||||||
let lock_resource = scanner_cache_lock_resource(DATA_USAGE_CACHE_NAME);
|
let lock_resource = scanner_cache_lock_resource(DATA_USAGE_CACHE_NAME, source);
|
||||||
let ns_lock = match store.new_ns_lock(RUSTFS_META_BUCKET, &lock_resource).await {
|
let ns_lock = match store.new_ns_lock(RUSTFS_META_BUCKET, &lock_resource).await {
|
||||||
Ok(lock) => lock,
|
Ok(lock) => lock,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
@@ -3080,11 +3094,11 @@ impl ScannerIOCache for SetDisks {
|
|||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
// Lock order: scanner leader fence -> per-bucket cache lock ->
|
// Lock order: scanner leader fence -> set-scoped per-bucket cache lock ->
|
||||||
// cache object read/write. The cache lock stays outermost for
|
// cache object read/write. The cache lock stays outermost for
|
||||||
// local and rolling-upgrade workers so leader failover cannot
|
// local and rolling-upgrade workers so leader failover cannot
|
||||||
// execute the same bucket concurrently.
|
// execute the same bucket concurrently.
|
||||||
let lock_resource = scanner_cache_lock_resource(&cache_name);
|
let lock_resource = scanner_cache_lock_resource(&cache_name, source);
|
||||||
let ns_lock = match store_clone_clone.new_ns_lock(RUSTFS_META_BUCKET, &lock_resource).await {
|
let ns_lock = match store_clone_clone.new_ns_lock(RUSTFS_META_BUCKET, &lock_resource).await {
|
||||||
Ok(lock) => lock,
|
Ok(lock) => lock,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
|
|||||||
Reference in New Issue
Block a user