mirror of
https://github.com/neondatabase/neon.git
synced 2026-01-10 06:52:55 +00:00
Allow already existing repo when creating a tenant
This commit is contained in:
committed by
Kirill Bulatov
parent
dd74c66ef0
commit
fe6fccfdae
@@ -220,7 +220,7 @@ paths:
|
||||
format: hex
|
||||
responses:
|
||||
"201":
|
||||
description: CREATED
|
||||
description: Already exists or created
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
|
||||
@@ -9,11 +9,11 @@ use crate::thread_mgr::ThreadKind;
|
||||
use crate::timelines;
|
||||
use crate::walredo::PostgresRedoManager;
|
||||
use crate::CheckpointConfig;
|
||||
use anyhow::{bail, Context, Result};
|
||||
use anyhow::{Context, Result};
|
||||
use lazy_static::lazy_static;
|
||||
use log::*;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::collections::{hash_map, HashMap};
|
||||
use std::collections::HashMap;
|
||||
use std::fmt;
|
||||
use std::sync::{Arc, Mutex, MutexGuard};
|
||||
use zenith_utils::zid::{ZTenantId, ZTimelineId};
|
||||
@@ -183,16 +183,16 @@ pub fn create_repository_for_tenant(
|
||||
) -> Result<ZTenantId> {
|
||||
let new_tenant_id = new_tenant_id.unwrap_or_else(ZTenantId::generate);
|
||||
let wal_redo_manager = Arc::new(PostgresRedoManager::new(conf, new_tenant_id));
|
||||
let repo = timelines::create_repo(conf, new_tenant_id, wal_redo_manager)?;
|
||||
|
||||
match access_tenants().entry(new_tenant_id) {
|
||||
hash_map::Entry::Occupied(_) => bail!("tenant {} already exists", new_tenant_id),
|
||||
hash_map::Entry::Vacant(v) => {
|
||||
v.insert(Tenant {
|
||||
state: TenantState::Idle,
|
||||
repo,
|
||||
});
|
||||
match timelines::create_repo(conf, new_tenant_id, wal_redo_manager)? {
|
||||
Some(repo) => {
|
||||
access_tenants()
|
||||
.entry(new_tenant_id)
|
||||
.or_insert_with(|| Tenant {
|
||||
state: TenantState::Idle,
|
||||
repo,
|
||||
});
|
||||
}
|
||||
None => debug!("repository already exists for tenant {}", new_tenant_id),
|
||||
}
|
||||
|
||||
Ok(new_tenant_id)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
//! Timeline management code
|
||||
//
|
||||
|
||||
use anyhow::{bail, Context, Result};
|
||||
use anyhow::{anyhow, bail, Context, Result};
|
||||
use postgres_ffi::ControlFileData;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::{
|
||||
@@ -160,7 +160,7 @@ pub fn init_pageserver(
|
||||
conf: &'static PageServerConf,
|
||||
create_tenant: Option<ZTenantId>,
|
||||
initial_timeline_id: Option<ZTimelineId>,
|
||||
) -> Result<()> {
|
||||
) -> anyhow::Result<()> {
|
||||
// Initialize logger
|
||||
// use true as daemonize parameter because otherwise we pollute zenith cli output with a few pages long output of info messages
|
||||
let _log_file = logging::init(LOG_FILE_NAME, true)?;
|
||||
@@ -177,9 +177,13 @@ pub fn init_pageserver(
|
||||
// anymore, but I think that could still happen.
|
||||
let dummy_redo_mgr = Arc::new(crate::walredo::DummyRedoManager {});
|
||||
|
||||
crashsafe_dir::create_dir_all(conf.tenants_path())?;
|
||||
|
||||
if let Some(tenant_id) = create_tenant {
|
||||
println!("initializing tenantid {}", tenant_id);
|
||||
let repo = create_repo(conf, tenant_id, dummy_redo_mgr).context("failed to create repo")?;
|
||||
let repo = create_repo(conf, tenant_id, dummy_redo_mgr)
|
||||
.context("failed to create repo")?
|
||||
.ok_or_else(|| anyhow!("For newely created pageserver, found already existing repository for tenant {}", tenant_id))?;
|
||||
let new_timeline_id = initial_timeline_id.unwrap_or_else(ZTimelineId::generate);
|
||||
bootstrap_timeline(conf, tenant_id, new_timeline_id, repo.as_ref())
|
||||
.context("failed to create initial timeline")?;
|
||||
@@ -187,7 +191,6 @@ pub fn init_pageserver(
|
||||
} else if initial_timeline_id.is_some() {
|
||||
println!("Ignoring initial timeline parameter, due to no tenant id to create given");
|
||||
}
|
||||
crashsafe_dir::create_dir_all(conf.tenants_path())?;
|
||||
|
||||
println!("pageserver init succeeded");
|
||||
Ok(())
|
||||
@@ -197,26 +200,25 @@ pub fn create_repo(
|
||||
conf: &'static PageServerConf,
|
||||
tenant_id: ZTenantId,
|
||||
wal_redo_manager: Arc<dyn WalRedoManager + Send + Sync>,
|
||||
) -> Result<Arc<dyn Repository>> {
|
||||
) -> Result<Option<Arc<dyn Repository>>> {
|
||||
let repo_dir = conf.tenant_path(&tenant_id);
|
||||
if repo_dir.exists() {
|
||||
bail!("repo for {} already exists", tenant_id)
|
||||
debug!("repo for {} already exists", tenant_id);
|
||||
return Ok(None);
|
||||
}
|
||||
|
||||
// top-level dir may exist if we are creating it through CLI
|
||||
crashsafe_dir::create_dir_all(&repo_dir)
|
||||
.with_context(|| format!("could not create directory {}", repo_dir.display()))?;
|
||||
|
||||
crashsafe_dir::create_dir(conf.timelines_path(&tenant_id))?;
|
||||
|
||||
info!("created directory structure in {}", repo_dir.display());
|
||||
|
||||
Ok(Arc::new(LayeredRepository::new(
|
||||
Ok(Some(Arc::new(LayeredRepository::new(
|
||||
conf,
|
||||
wal_redo_manager,
|
||||
tenant_id,
|
||||
conf.remote_storage_config.is_some(),
|
||||
)))
|
||||
))))
|
||||
}
|
||||
|
||||
// Returns checkpoint LSN from controlfile
|
||||
|
||||
Reference in New Issue
Block a user