mirror of
https://github.com/neondatabase/neon.git
synced 2026-01-03 19:42:55 +00:00
A few more PS changes (#12552)
# TLDR Problem-I is a bug fix. The rest are no-ops. ## Problem I Page server checks image layer creation based on the elapsed time but this check depends on the current logical size, which is only computed on shard 0. Thus, for non-0 shards, the check will be ineffective and image creation will never be done for idle tenants. ## Summary of changes I This PR fixes the problem by simply removing the dependency on current logical size. ## Summary of changes II This PR adds a timeout when calling page server to split shard to make sure SC does not wait for the API call forever. Currently the PR doesn't adds any retry logic because it's not clear whether page server shard split can be safely retried if the existing operation is still ongoing or left the storage in a bad state. Thus it's better to abort the whole operation and restart. ## Problem III `test_remote_failures` requires PS to be compiled in the testing mode. For PS in dev/staging, they are compiled without this mode. ## Summary of changes III Remove the restriction and also increase the number of total failures allowed. ## Summary of changes IV remove test on PS getpage http route. --------- Co-authored-by: Chen Luo <chen.luo@databricks.com> Co-authored-by: Yecheng Yang <carlton.yang@databricks.com> Co-authored-by: Vlad Lazar <vlad@neon.tech>
This commit is contained in:
@@ -222,6 +222,9 @@ struct Cli {
|
||||
/// Primarily useful for testing to reduce test execution time.
|
||||
#[arg(long, default_value = "false", action=ArgAction::Set)]
|
||||
kick_secondary_downloads: bool,
|
||||
|
||||
#[arg(long)]
|
||||
shard_split_request_timeout: Option<humantime::Duration>,
|
||||
}
|
||||
|
||||
enum StrictMode {
|
||||
@@ -470,6 +473,10 @@ async fn async_main() -> anyhow::Result<()> {
|
||||
timeline_safekeeper_count: args.timeline_safekeeper_count,
|
||||
posthog_config: posthog_config.clone(),
|
||||
kick_secondary_downloads: args.kick_secondary_downloads,
|
||||
shard_split_request_timeout: args
|
||||
.shard_split_request_timeout
|
||||
.map(humantime::Duration::into)
|
||||
.unwrap_or(Duration::MAX),
|
||||
};
|
||||
|
||||
// Validate that we can connect to the database
|
||||
|
||||
@@ -60,6 +60,7 @@ use tokio::sync::mpsc::error::TrySendError;
|
||||
use tokio_util::sync::CancellationToken;
|
||||
use tracing::{Instrument, debug, error, info, info_span, instrument, warn};
|
||||
use utils::completion::Barrier;
|
||||
use utils::env;
|
||||
use utils::generation::Generation;
|
||||
use utils::id::{NodeId, TenantId, TimelineId};
|
||||
use utils::lsn::Lsn;
|
||||
@@ -483,6 +484,9 @@ pub struct Config {
|
||||
|
||||
/// When set, actively checks and initiates heatmap downloads/uploads.
|
||||
pub kick_secondary_downloads: bool,
|
||||
|
||||
/// Timeout used for HTTP client of split requests. [`Duration::MAX`] if None.
|
||||
pub shard_split_request_timeout: Duration,
|
||||
}
|
||||
|
||||
impl From<DatabaseError> for ApiError {
|
||||
@@ -6406,18 +6410,39 @@ impl Service {
|
||||
// TODO: issue split calls concurrently (this only matters once we're splitting
|
||||
// N>1 shards into M shards -- initially we're usually splitting 1 shard into N).
|
||||
|
||||
// HADRON: set a timeout for splitting individual shards on page servers.
|
||||
// Currently we do not perform any retry because it's not clear if page server can handle
|
||||
// partially split shards correctly.
|
||||
let shard_split_timeout =
|
||||
if let Some(env::DeploymentMode::Local) = env::get_deployment_mode() {
|
||||
Duration::from_secs(30)
|
||||
} else {
|
||||
self.config.shard_split_request_timeout
|
||||
};
|
||||
let mut http_client_builder = reqwest::ClientBuilder::new()
|
||||
.pool_max_idle_per_host(0)
|
||||
.timeout(shard_split_timeout);
|
||||
|
||||
for ssl_ca_cert in &self.config.ssl_ca_certs {
|
||||
http_client_builder = http_client_builder.add_root_certificate(ssl_ca_cert.clone());
|
||||
}
|
||||
let http_client = http_client_builder
|
||||
.build()
|
||||
.expect("Failed to construct HTTP client");
|
||||
for target in &targets {
|
||||
let ShardSplitTarget {
|
||||
parent_id,
|
||||
node,
|
||||
child_ids,
|
||||
} = target;
|
||||
|
||||
let client = PageserverClient::new(
|
||||
node.get_id(),
|
||||
self.http_client.clone(),
|
||||
http_client.clone(),
|
||||
node.base_url(),
|
||||
self.config.pageserver_jwt_token.as_deref(),
|
||||
);
|
||||
|
||||
let response = client
|
||||
.tenant_shard_split(
|
||||
*parent_id,
|
||||
|
||||
Reference in New Issue
Block a user