Skip to content

Commit

Permalink
Make {DeltaLayer,ImageLayer}::{load,load_inner} async (#4883)
Browse files Browse the repository at this point in the history
## Problem

The functions `DeltaLayer::load_inner` and `ImageLayer::load_inner` are
calling `read_blk` internally, which we would like to turn into an async
fn.

## Summary of changes

We switch from `once_cell`'s `OnceCell` implementation to the one in
`tokio` in order to be able to call an async `get_or_try_init` function.

Builds on top of #4839, part of #4743
  • Loading branch information
arpad-m authored Aug 4, 2023
1 parent 682dfb3 commit 6a906c6
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 13 deletions.
21 changes: 13 additions & 8 deletions pageserver/src/tenant/storage_layer/delta_layer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ use crate::virtual_file::VirtualFile;
use crate::{walrecord, TEMP_FILE_SUFFIX};
use crate::{DELTA_FILE_MAGIC, STORAGE_FORMAT_VERSION};
use anyhow::{bail, ensure, Context, Result};
use once_cell::sync::OnceCell;
use pageserver_api::models::{HistoricLayerInfo, LayerAccessKind};
use rand::{distributions::Alphanumeric, Rng};
use serde::{Deserialize, Serialize};
Expand All @@ -52,6 +51,7 @@ use std::ops::Range;
use std::os::unix::fs::FileExt;
use std::path::{Path, PathBuf};
use std::sync::Arc;
use tokio::sync::OnceCell;
use tracing::*;

use utils::{
Expand Down Expand Up @@ -242,7 +242,7 @@ impl Layer for DeltaLayer {
return Ok(());
}

let inner = self.load(LayerAccessKind::Dump, ctx)?;
let inner = self.load(LayerAccessKind::Dump, ctx).await?;

println!(
"index_start_blk: {}, root {}",
Expand Down Expand Up @@ -317,7 +317,9 @@ impl Layer for DeltaLayer {

{
// Open the file and lock the metadata in memory
let inner = self.load(LayerAccessKind::GetValueReconstructData, ctx)?;
let inner = self
.load(LayerAccessKind::GetValueReconstructData, ctx)
.await?;

// Scan the page versions backwards, starting from `lsn`.
let file = &inner.file;
Expand Down Expand Up @@ -497,7 +499,7 @@ impl DeltaLayer {
/// Open the underlying file and read the metadata into memory, if it's
/// not loaded already.
///
fn load(
async fn load(
&self,
access_kind: LayerAccessKind,
ctx: &RequestContext,
Expand All @@ -507,10 +509,11 @@ impl DeltaLayer {
// Quick exit if already loaded
self.inner
.get_or_try_init(|| self.load_inner())
.await
.with_context(|| format!("Failed to load delta layer {}", self.path().display()))
}

fn load_inner(&self) -> Result<Arc<DeltaLayerInner>> {
async fn load_inner(&self) -> Result<Arc<DeltaLayerInner>> {
let path = self.path();

let file = VirtualFile::open(&path)
Expand Down Expand Up @@ -571,7 +574,7 @@ impl DeltaLayer {
file_size,
),
access_stats,
inner: once_cell::sync::OnceCell::new(),
inner: OnceCell::new(),
}
}

Expand All @@ -598,7 +601,7 @@ impl DeltaLayer {
metadata.len(),
),
access_stats: LayerAccessStats::empty_will_record_residence_event_later(),
inner: once_cell::sync::OnceCell::new(),
inner: OnceCell::new(),
})
}

Expand All @@ -621,6 +624,7 @@ impl DeltaLayer {
pub async fn load_val_refs(&self, ctx: &RequestContext) -> Result<Vec<(Key, Lsn, ValueRef)>> {
let inner = self
.load(LayerAccessKind::KeyIter, ctx)
.await
.context("load delta layer")?;
DeltaLayerInner::load_val_refs(inner)
.await
Expand All @@ -631,6 +635,7 @@ impl DeltaLayer {
pub async fn load_keys(&self, ctx: &RequestContext) -> Result<Vec<(Key, Lsn, u64)>> {
let inner = self
.load(LayerAccessKind::KeyIter, ctx)
.await
.context("load delta layer keys")?;
DeltaLayerInner::load_keys(inner)
.await
Expand Down Expand Up @@ -784,7 +789,7 @@ impl DeltaLayerWriterInner {
metadata.len(),
),
access_stats: LayerAccessStats::empty_will_record_residence_event_later(),
inner: once_cell::sync::OnceCell::new(),
inner: OnceCell::new(),
};

// fsync the file
Expand Down
17 changes: 12 additions & 5 deletions pageserver/src/tenant/storage_layer/image_layer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ use crate::{IMAGE_FILE_MAGIC, STORAGE_FORMAT_VERSION, TEMP_FILE_SUFFIX};
use anyhow::{bail, ensure, Context, Result};
use bytes::Bytes;
use hex;
use once_cell::sync::OnceCell;
use pageserver_api::models::{HistoricLayerInfo, LayerAccessKind};
use rand::{distributions::Alphanumeric, Rng};
use serde::{Deserialize, Serialize};
Expand All @@ -48,6 +47,7 @@ use std::io::{Seek, SeekFrom};
use std::ops::Range;
use std::os::unix::prelude::FileExt;
use std::path::{Path, PathBuf};
use tokio::sync::OnceCell;
use tracing::*;

use utils::{
Expand Down Expand Up @@ -168,7 +168,7 @@ impl Layer for ImageLayer {
return Ok(());
}

let inner = self.load(LayerAccessKind::Dump, ctx)?;
let inner = self.load(LayerAccessKind::Dump, ctx).await?;
let file = &inner.file;
let tree_reader =
DiskBtreeReader::<_, KEY_SIZE>::new(inner.index_start_blk, inner.index_root_blk, file);
Expand Down Expand Up @@ -197,7 +197,9 @@ impl Layer for ImageLayer {
assert!(lsn_range.start >= self.lsn);
assert!(lsn_range.end >= self.lsn);

let inner = self.load(LayerAccessKind::GetValueReconstructData, ctx)?;
let inner = self
.load(LayerAccessKind::GetValueReconstructData, ctx)
.await?;

let file = &inner.file;
let tree_reader = DiskBtreeReader::new(inner.index_start_blk, inner.index_root_blk, file);
Expand Down Expand Up @@ -314,7 +316,11 @@ impl ImageLayer {
/// Open the underlying file and read the metadata into memory, if it's
/// not loaded already.
///
fn load(&self, access_kind: LayerAccessKind, ctx: &RequestContext) -> Result<&ImageLayerInner> {
async fn load(
&self,
access_kind: LayerAccessKind,
ctx: &RequestContext,
) -> Result<&ImageLayerInner> {
self.access_stats
.record_access(access_kind, ctx.task_kind());
loop {
Expand All @@ -323,11 +329,12 @@ impl ImageLayer {
}
self.inner
.get_or_try_init(|| self.load_inner())
.await
.with_context(|| format!("Failed to load image layer {}", self.path().display()))?;
}
}

fn load_inner(&self) -> Result<ImageLayerInner> {
async fn load_inner(&self) -> Result<ImageLayerInner> {
let path = self.path();

// Open the file if it's not open already.
Expand Down

1 comment on commit 6a906c6

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1332 tests run: 1277 passed, 0 failed, 55 skipped (full report)


Flaky tests (1)

Postgres 15

  • test_crafted_wal_end[last_wal_record_crossing_segment]: debug

Please sign in to comment.