This commit is contained in:
Christian Schwarz
2024-02-02 11:50:43 +00:00
parent aa0e9fdaef
commit 014147a644
9 changed files with 189 additions and 23 deletions

View File

@@ -614,10 +614,7 @@ impl Tenant {
mode: SpawnMode,
ctx: &RequestContext,
) -> anyhow::Result<Arc<Tenant>> {
let wal_redo_manager = Arc::new(WalRedoManager::from(PostgresRedoManager::new(
conf,
tenant_shard_id,
)));
let wal_redo_manager = Arc::new(WalRedoManager::from(PostgresRedoManager::new(conf)));
let TenantSharedResources {
broker_client,

View File

@@ -21,6 +21,8 @@
/// Process lifecycle and abstracction for the IPC protocol.
mod process;
mod process_pool;
/// Code to apply [`NeonWalRecord`]s.
mod apply_neon;
@@ -146,6 +148,7 @@ impl PostgresRedoManager {
pub fn new(
conf: &'static PageServerConf,
tenant_shard_id: TenantShardId,
pool: process_pool::Pool,
) -> PostgresRedoManager {
// The actual process is launched lazily, on first request.
PostgresRedoManager {

View File

@@ -52,12 +52,8 @@ impl WalRedoProcess {
//
// Start postgres binary in special WAL redo mode.
//
#[instrument(skip_all,fields(tenant_id=%tenant_shard_id.tenant_id, shard_id=%tenant_shard_id.shard_slug(), pg_version=pg_version))]
pub(crate) fn launch(
conf: &'static PageServerConf,
tenant_shard_id: TenantShardId,
pg_version: u32,
) -> anyhow::Result<Self> {
#[instrument(skip_all,fields(pg_version=pg_version))]
pub(crate) fn launch(conf: &'static PageServerConf, pg_version: u32) -> anyhow::Result<Self> {
let pg_bin_dir_path = conf.pg_bin_dir(pg_version).context("pg_bin_dir")?; // TODO these should be infallible.
let pg_lib_dir_path = conf.pg_lib_dir(pg_version).context("pg_lib_dir")?;
@@ -66,9 +62,6 @@ impl WalRedoProcess {
let child = Command::new(pg_bin_dir_path.join("postgres"))
// the first arg must be --wal-redo so the child process enters into walredo mode
.arg("--wal-redo")
// the child doesn't process this arg, but, having it in the argv helps indentify the
// walredo process for a particular tenant when debugging a pagserver
.args(["--tenant-shard-id", &format!("{tenant_shard_id}")])
.stdin(Stdio::piped())
.stderr(Stdio::piped())
.stdout(Stdio::piped())
@@ -83,7 +76,7 @@ impl WalRedoProcess {
// the files it opens, and
// 2. to use seccomp to sandbox itself before processing the first
// walredo request.
.spawn_no_leak_child(tenant_shard_id)
.spawn_no_leak_child()
.context("spawn process")?;
WAL_REDO_PROCESS_COUNTERS.started.inc();
let mut child = scopeguard::guard(child, |child| {
@@ -144,12 +137,11 @@ impl WalRedoProcess {
error!(error=?e, "failed to read from walredo stderr");
}
}
}.instrument(tracing::info_span!(parent: None, "wal-redo-postgres-stderr", pid = child.id(), tenant_id = %tenant_shard_id.tenant_id, shard_id = %tenant_shard_id.shard_slug(), %pg_version))
}.instrument(tracing::info_span!(parent: None, "wal-redo-postgres-stderr", pid = child.id(), %pg_version))
);
Ok(Self {
conf,
tenant_shard_id,
child: Some(child),
stdin: Mutex::new(ProcessInput {
stdin,
@@ -175,7 +167,7 @@ impl WalRedoProcess {
// Apply given WAL records ('records') over an old page image. Returns
// new page image.
//
#[instrument(skip_all, fields(tenant_id=%self.tenant_shard_id.tenant_id, shard_id=%self.tenant_shard_id.shard_slug(), pid=%self.id()))]
#[instrument(skip_all, fields(pid=%self.id()))]
pub(crate) fn apply_wal_records(
&self,
rel: RelTag,

View File

@@ -20,7 +20,6 @@ use pageserver_api::shard::TenantShardId;
/// Wrapper type around `std::process::Child` which guarantees that the child
/// will be killed and waited-for by this process before being dropped.
pub(crate) struct NoLeakChild {
pub(crate) tenant_id: TenantShardId,
pub(crate) child: Option<Child>,
}
@@ -39,12 +38,9 @@ impl DerefMut for NoLeakChild {
}
impl NoLeakChild {
pub(crate) fn spawn(tenant_id: TenantShardId, command: &mut Command) -> io::Result<Self> {
pub(crate) fn spawn(command: &mut Command) -> io::Result<Self> {
let child = command.spawn()?;
Ok(NoLeakChild {
tenant_id,
child: Some(child),
})
Ok(NoLeakChild { child: Some(child) })
}
pub(crate) fn kill_and_wait(mut self, cause: WalRedoKillCause) {

View File

@@ -0,0 +1,36 @@
use std::sync::Arc;
use utils::pre_spawned_pool;
use crate::config::PageServerConf;
use super::process::WalRedoProcess;
pub struct Pool {
v14: pre_spawned_pool::Pool<Arc<WalRedoProcess>, Launcher>,
v15: pre_spawned_pool::Pool<Arc<WalRedoProcess>, Launcher>,
v16: pre_spawned_pool::Pool<Arc<WalRedoProcess>, Launcher>,
}
struct Launcher {
pg_version: u32,
conf: &'static PageServerConf,
}
impl utils::pre_spawned_pool::Launcher<Arc<WalRedoProcess>> for Launcher{
fn create(&self) -> anyhow::Result<Arc<WalRedoProcess>> {
WalRedoProcess::launch(self.conf, self.pg_version)
}
}
impl Pool {
pub fn get(&self, pg_version: usize) -> anyhow::Result<Arc<WalRedoProcess>> {
let pool = match pg_version {
14 => &self.v14,
15 => &self.v15,
16 => &self.v16,
x => anyhow::bail!("unknown pg version: {x}"),
};
pool.get()
}
}