diff options
author | Alex <lx@deuxfleurs.fr> | 2025-02-14 15:53:16 +0000 |
---|---|---|
committer | Alex <lx@deuxfleurs.fr> | 2025-02-14 15:53:16 +0000 |
commit | 9312c6bbcbd9c47bffa57baaee4efd40d418f62b (patch) | |
tree | 039d580983ae1f04235e7e5e36cbf64f23e89e7e /src/block | |
parent | 3fe8db9e52bf7fd069d8fa11d6a0c90a7d2944b6 (diff) | |
parent | fdf4dad72833264be6bc4bae70f4e743e656d2df (diff) | |
download | garage-9312c6bbcbd9c47bffa57baaee4efd40d418f62b.tar.gz garage-9312c6bbcbd9c47bffa57baaee4efd40d418f62b.zip |
Merge pull request 'Store data blocks only on nodes in the latest cluster layout version (fix #815)' (#956) from fix-815 into main
Reviewed-on: https://git.deuxfleurs.fr/Deuxfleurs/garage/pulls/956
Diffstat (limited to 'src/block')
-rw-r--r-- | src/block/manager.rs | 4 | ||||
-rw-r--r-- | src/block/resync.rs | 24 |
2 files changed, 25 insertions, 3 deletions
diff --git a/src/block/manager.rs b/src/block/manager.rs index 537e1fc1..572bdadd 100644 --- a/src/block/manager.rs +++ b/src/block/manager.rs @@ -370,7 +370,7 @@ impl BlockManager { prevent_compression: bool, order_tag: Option<OrderTag>, ) -> Result<(), Error> { - let who = self.replication.write_sets(&hash); + let who = self.system.cluster_layout().current_storage_nodes_of(&hash); let compression_level = self.compression_level.filter(|_| !prevent_compression); let (header, bytes) = DataBlock::from_buffer(data, compression_level) @@ -396,7 +396,7 @@ impl BlockManager { .rpc_helper() .try_write_many_sets( &self.endpoint, - who.as_ref(), + &[who], put_block_rpc, RequestStrategy::with_priority(PRIO_NORMAL | PRIO_SECONDARY) .with_drop_on_completion(permit) diff --git a/src/block/resync.rs b/src/block/resync.rs index 947c68de..b476a0b8 100644 --- a/src/block/resync.rs +++ b/src/block/resync.rs @@ -377,7 +377,10 @@ impl BlockResyncManager { info!("Resync block {:?}: offloading and deleting", hash); let existing_path = existing_path.unwrap(); - let mut who = manager.replication.storage_nodes(hash); + let mut who = manager + .system + .cluster_layout() + .current_storage_nodes_of(hash); if who.len() < manager.replication.write_quorum() { return Err(Error::Message("Not trying to offload block because we don't have a quorum of nodes to write to".to_string())); } @@ -455,6 +458,25 @@ impl BlockResyncManager { } if rc.is_nonzero() && !exists { + // The refcount is > 0, and the block is not present locally. + // We might need to fetch it from another node. + + // First, check whether we are still supposed to store that + // block in the latest cluster layout version. + let storage_nodes = manager + .system + .cluster_layout() + .current_storage_nodes_of(&hash); + + if !storage_nodes.contains(&manager.system.id) { + info!( + "Resync block {:?}: block is absent with refcount > 0, but it will drop to zero after all metadata is synced. Not fetching the block.", + hash + ); + return Ok(()); + } + + // We know we need the block. Fetch it. info!( "Resync block {:?}: fetching absent but needed block (refcount > 0)", hash |