diff --git a/pageserver/src/tenant/timeline.rs b/pageserver/src/tenant/timeline.rs index d7ff70a29ce1..7b6c6dbfadce 100644 --- a/pageserver/src/tenant/timeline.rs +++ b/pageserver/src/tenant/timeline.rs @@ -1724,11 +1724,18 @@ impl Timeline { for (name, decision) in decided { let decision = match decision { Ok(UseRemote { local, remote }) => { - path.push(name.file_name()); - init::cleanup_local_file_for_remote(&path, &local, &remote)?; - path.pop(); - - UseRemote { local, remote } + // Remote is authoritative, but we may still choose to retain + // the local file if the contents appear to match + if local.file_size() == remote.file_size() { + // Use the local file, but take the remote metadata so that we pick up + // the correct generation. + UseLocal(remote) + } else { + path.push(name.file_name()); + init::cleanup_local_file_for_remote(&path, &local, &remote)?; + path.pop(); + UseRemote { local, remote } + } } Ok(decision) => decision, Err(FutureLayer { local }) => { diff --git a/pageserver/src/tenant/timeline/init.rs b/pageserver/src/tenant/timeline/init.rs index 33effb431878..22976a514df7 100644 --- a/pageserver/src/tenant/timeline/init.rs +++ b/pageserver/src/tenant/timeline/init.rs @@ -147,11 +147,7 @@ pub(super) fn reconcile( Err(FutureLayer { local }) } else { Ok(match (local, remote) { - (Some(local), Some(remote)) if local != remote => { - assert_eq!(local.generation, remote.generation); - - UseRemote { local, remote } - } + (Some(local), Some(remote)) if local != remote => UseRemote { local, remote }, (Some(x), Some(_)) => UseLocal(x), (None, Some(x)) => Evicted(x), (Some(x), None) => NeedsUpload(x),