On tenant load, start WAL receivers only after all timelines have been loaded.

And similarly on attach. This way, if the tenant load/attach fails
halfway through, we don't have any leftover WAL receivers still
running on the broken tenant.
This commit is contained in:
Heikki Linnakangas
2022-11-24 15:49:04 +02:00
committed by Christian Schwarz
parent 0260ee23b9
commit dc9c33139b
2 changed files with 14 additions and 6 deletions

View File

@@ -44,7 +44,8 @@ impl TenantState {
/// A state of a timeline in pageserver's memory.
#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
pub enum TimelineState {
/// Timeline is fully operational, its background jobs are running.
/// Timeline is fully operational. If the containing Tenant is Active, the timeline's
/// background jobs are running otherwise they will be launched when the tenant is activated.
Active,
/// A timeline is recognized by pageserver, but not yet ready to operate.
/// The status indicates, that the timeline could eventually go back to Active automatically:

View File

@@ -165,12 +165,21 @@ struct TimelineUninitMark {
}
impl UninitializedTimeline<'_> {
/// Ensures timeline data is valid, loads it into pageserver's memory and removes uninit mark file on success.
/// Ensures timeline data is valid, loads it into pageserver's memory and removes
/// uninit mark file on success.
///
/// The new timeline is initialized in Active state, and its background jobs are
/// started
pub fn initialize(self) -> anyhow::Result<Arc<Timeline>> {
let mut timelines = self.owning_tenant.timelines.lock().unwrap();
self.initialize_with_lock(&mut timelines, true, true)
}
/// Like `initialize`, but the caller is already holding lock on Tenant::timelines.
/// If `launch_wal_receiver` is false, the WAL receiver not launched, even though
/// timeline is initialized in Active state. This is used during tenant load and
/// attach, where the WAL receivers are launched only after all the timelines have
/// been initialized.
fn initialize_with_lock(
mut self,
timelines: &mut HashMap<TimelineId, Arc<Timeline>>,
@@ -403,7 +412,7 @@ struct RemoteStartupData {
/// timelines, forked off from the same initial call to 'initdb'.
impl Tenant {
/// Yet another helper for timeline initialization.
/// Contains common part for `load_remote_timeline` and `load_remote_timeline`
/// Contains common part for `load_local_timeline` and `load_remote_timeline`
async fn setup_timeline(
&self,
timeline_id: TimelineId,
@@ -502,9 +511,6 @@ impl Tenant {
.context("save_metadata")?;
}
// Finally launch walreceiver
timeline.launch_wal_receiver();
Ok(())
}
@@ -1301,6 +1307,7 @@ impl Tenant {
for timeline in not_broken_timelines {
timeline.set_state(TimelineState::Active);
timeline.launch_wal_receiver();
}
}
}