mirror of
https://github.com/neondatabase/neon.git
synced 2026-05-29 19:10:38 +00:00
Refactor timeline creation on safekeepers, allowing storing peer ids.
Have separate routine and http endpoint to create timeline on safekeepers. It is not used yet, i.e. timeline is still created implicitly, but we'll change that once infrastructure for learning which tlis are assigned to which safekeepers will be ready, preventing accidental creation by compute. Changes format of safekeeper control file, allowing to store set of peers. Knowing peers provides a part of foundation for peer recovery (calculating min horizons like truncate_lsn for WAL truncation and commit_lsn for sync-safekeepers replacement) and proper membership change; similarly, we don't yet use it for now. Employing cf file version bump, extracts tenant_id and timeline_id to top level where it is more suitable. Also adds a bunch of LSNs there and rename truncate_lsn to more specific peer_horizon_lsn.
This commit is contained in:
@@ -13,6 +13,7 @@ use postgres_ffi::xlog_utils::PG_TLI;
|
||||
use regex::Regex;
|
||||
use std::str::FromStr;
|
||||
use std::sync::Arc;
|
||||
use tracing::info;
|
||||
use zenith_utils::lsn::Lsn;
|
||||
use zenith_utils::postgres_backend;
|
||||
use zenith_utils::postgres_backend::PostgresBackend;
|
||||
@@ -20,7 +21,6 @@ use zenith_utils::pq_proto::{BeMessage, FeStartupPacket, RowDescriptor, INT4_OID
|
||||
use zenith_utils::zid::{ZTenantId, ZTenantTimelineId, ZTimelineId};
|
||||
|
||||
use crate::callmemaybe::CallmeEvent;
|
||||
use crate::control_file::CreateControlFile;
|
||||
use tokio::sync::mpsc::UnboundedSender;
|
||||
|
||||
/// Safekeeper handler of postgres commands
|
||||
@@ -101,29 +101,19 @@ impl postgres_backend::Handler for SafekeeperPostgresHandler {
|
||||
fn process_query(&mut self, pgb: &mut PostgresBackend, query_string: &str) -> Result<()> {
|
||||
let cmd = parse_cmd(query_string)?;
|
||||
|
||||
// Is this command is ztimeline scoped?
|
||||
match cmd {
|
||||
SafekeeperPostgresCommand::StartWalPush { .. }
|
||||
| SafekeeperPostgresCommand::StartReplication { .. }
|
||||
| SafekeeperPostgresCommand::IdentifySystem
|
||||
| SafekeeperPostgresCommand::JSONCtrl { .. } => {
|
||||
let tenantid = self.ztenantid.context("tenantid is required")?;
|
||||
let timelineid = self.ztimelineid.context("timelineid is required")?;
|
||||
if self.timeline.is_none() {
|
||||
// START_WAL_PUSH is the only command that initializes the timeline in production.
|
||||
// There is also JSON_CTRL command, which should initialize the timeline for testing.
|
||||
let create_control_file = match cmd {
|
||||
SafekeeperPostgresCommand::StartWalPush { .. }
|
||||
| SafekeeperPostgresCommand::JSONCtrl { .. } => CreateControlFile::True,
|
||||
_ => CreateControlFile::False,
|
||||
};
|
||||
self.timeline.set(
|
||||
&self.conf,
|
||||
ZTenantTimelineId::new(tenantid, timelineid),
|
||||
create_control_file,
|
||||
)?;
|
||||
}
|
||||
}
|
||||
info!("got query {:?}", query_string);
|
||||
|
||||
let create = !(matches!(cmd, SafekeeperPostgresCommand::StartReplication { .. })
|
||||
|| matches!(cmd, SafekeeperPostgresCommand::IdentifySystem));
|
||||
|
||||
let tenantid = self.ztenantid.context("tenantid is required")?;
|
||||
let timelineid = self.ztimelineid.context("timelineid is required")?;
|
||||
if self.timeline.is_none() {
|
||||
self.timeline.set(
|
||||
&self.conf,
|
||||
ZTenantTimelineId::new(tenantid, timelineid),
|
||||
create,
|
||||
)?;
|
||||
}
|
||||
|
||||
match cmd {
|
||||
|
||||
Reference in New Issue
Block a user