diff --git a/pageserver/src/tenant/storage_layer.rs b/pageserver/src/tenant/storage_layer.rs index 6e9a4932d8..7a1912c005 100644 --- a/pageserver/src/tenant/storage_layer.rs +++ b/pageserver/src/tenant/storage_layer.rs @@ -65,6 +65,7 @@ where pub struct ValueReconstructState { pub records: Vec<(Lsn, NeonWalRecord)>, pub img: Option<(Lsn, Bytes)>, + pub(crate) scratch: Vec, } /// Return value from [`Layer::get_value_reconstruct_data`] diff --git a/pageserver/src/tenant/storage_layer/delta_layer.rs b/pageserver/src/tenant/storage_layer/delta_layer.rs index 3e7a8e10e5..12fef3009b 100644 --- a/pageserver/src/tenant/storage_layer/delta_layer.rs +++ b/pageserver/src/tenant/storage_layer/delta_layer.rs @@ -778,15 +778,14 @@ impl DeltaLayerInner { // Ok, 'offsets' now contains the offsets of all the entries we need to read let cursor = file.block_cursor(); - let mut buf = Vec::new(); for (entry_lsn, pos) in offsets { cursor - .read_blob_into_buf(pos, &mut buf, ctx) + .read_blob_into_buf(pos, &mut reconstruct_state.scratch, ctx) .await .with_context(|| { format!("Failed to read blob from virtual file {}", file.file.path) })?; - let val = Value::des(&buf).with_context(|| { + let val = Value::des(&reconstruct_state.scratch).with_context(|| { format!( "Failed to deserialize file blob from virtual file {}", file.file.path diff --git a/pageserver/src/tenant/timeline.rs b/pageserver/src/tenant/timeline.rs index 95f5d0eeec..bc6fe8970c 100644 --- a/pageserver/src/tenant/timeline.rs +++ b/pageserver/src/tenant/timeline.rs @@ -601,6 +601,7 @@ impl Timeline { let mut reconstruct_state = ValueReconstructState { records: Vec::new(), img: None, + scratch: Vec::with_capacity(2 * 8192), // for good measure }; let timer = crate::metrics::GET_RECONSTRUCT_DATA_TIME.start_timer();