From d45eca992ffd28a9a91aa1c2878816129a439088 Mon Sep 17 00:00:00 2001 From: Vlad Lazar Date: Tue, 16 Apr 2024 14:06:58 +0100 Subject: [PATCH] pageserver: validate singular vectored get results --- pageserver/src/tenant.rs | 12 ++++++++++-- pageserver/src/tenant/timeline.rs | 14 ++++++++++---- 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/pageserver/src/tenant.rs b/pageserver/src/tenant.rs index ed5c35cd5f..bf70b28e25 100644 --- a/pageserver/src/tenant.rs +++ b/pageserver/src/tenant.rs @@ -3862,6 +3862,7 @@ mod tests { use pageserver_api::keyspace::KeySpace; use rand::{thread_rng, Rng}; use tests::timeline::{GetVectoredError, ShutdownMode}; + use tests::storage_layer::ValuesReconstructState; static TEST_KEY: Lazy = Lazy::new(|| Key::from_slice(&hex!("010000000033333333444444445500000001"))); @@ -4649,7 +4650,9 @@ mod tests { for read in reads { info!("Doing vectored read on {:?}", read); - let vectored_res = tline.get_vectored_impl(read.clone(), reads_lsn, &ctx).await; + let vectored_res = tline + .get_vectored_impl(read.clone(), reads_lsn, ValuesReconstructState::new(), &ctx) + .await; tline .validate_get_vectored_impl(&vectored_res, read, reads_lsn, &ctx) .await; @@ -4844,7 +4847,12 @@ mod tests { ranges: vec![key_near_gap..gap_at_key.next(), key_near_end..current_key], }; let results = child_timeline - .get_vectored_impl(read.clone(), current_lsn, &ctx) + .get_vectored_impl( + read.clone(), + current_lsn, + ValuesReconstructState::new(), + &ctx, + ) .await?; for (key, img_res) in results { diff --git a/pageserver/src/tenant/timeline.rs b/pageserver/src/tenant/timeline.rs index c10c2bda7d..5fb576ffe1 100644 --- a/pageserver/src/tenant/timeline.rs +++ b/pageserver/src/tenant/timeline.rs @@ -751,10 +751,16 @@ impl Timeline { key_state.img = cached_page_img; reconstruct_state.keys.insert(key, Ok(key_state)); - let mut key_values = self - .get_vectored_impl(keyspace, lsn, reconstruct_state, ctx) - .await?; - let key_value = key_values.pop_first(); + let vectored_res = self + .get_vectored_impl(keyspace.clone(), lsn, reconstruct_state, ctx) + .await; + + if self.conf.validate_vectored_get { + self.validate_get_vectored_impl(&vectored_res, keyspace, lsn, ctx) + .await; + } + + let key_value = vectored_res?.pop_first(); match key_value { Some((got_key, value)) => { if got_key != key {