LCOV - code coverage report
Current view: top level - libs/pageserver_api/src - config.rs (source / functions) Coverage Total Hit
Test: 91bf6c8f32e5e69adde6241313e732fdd6d6e277.info Lines: 88.9 % 171 152
Test Date: 2025-03-04 12:19:20 Functions: 3.4 % 203 7

            Line data    Source code
       1              : use camino::Utf8PathBuf;
       2              : 
       3              : #[cfg(test)]
       4              : mod tests;
       5              : 
       6              : use const_format::formatcp;
       7              : pub const DEFAULT_PG_LISTEN_PORT: u16 = 64000;
       8              : pub const DEFAULT_PG_LISTEN_ADDR: &str = formatcp!("127.0.0.1:{DEFAULT_PG_LISTEN_PORT}");
       9              : pub const DEFAULT_HTTP_LISTEN_PORT: u16 = 9898;
      10              : pub const DEFAULT_HTTP_LISTEN_ADDR: &str = formatcp!("127.0.0.1:{DEFAULT_HTTP_LISTEN_PORT}");
      11              : 
      12              : use std::collections::HashMap;
      13              : use std::num::{NonZeroU64, NonZeroUsize};
      14              : use std::str::FromStr;
      15              : use std::time::Duration;
      16              : 
      17              : use postgres_backend::AuthType;
      18              : use remote_storage::RemoteStorageConfig;
      19              : use serde_with::serde_as;
      20              : use utils::logging::LogFormat;
      21              : use utils::postgres_client::PostgresClientProtocol;
      22              : 
      23              : use crate::models::{ImageCompressionAlgorithm, LsnLease};
      24              : 
      25              : // Certain metadata (e.g. externally-addressable name, AZ) is delivered
      26              : // as a separate structure.  This information is not neeed by the pageserver
      27              : // itself, it is only used for registering the pageserver with the control
      28              : // plane and/or storage controller.
      29              : //
      30            4 : #[derive(PartialEq, Eq, Debug, serde::Serialize, serde::Deserialize)]
      31              : pub struct NodeMetadata {
      32              :     #[serde(rename = "host")]
      33              :     pub postgres_host: String,
      34              :     #[serde(rename = "port")]
      35              :     pub postgres_port: u16,
      36              :     pub http_host: String,
      37              :     pub http_port: u16,
      38              : 
      39              :     // Deployment tools may write fields to the metadata file beyond what we
      40              :     // use in this type: this type intentionally only names fields that require.
      41              :     #[serde(flatten)]
      42              :     pub other: HashMap<String, serde_json::Value>,
      43              : }
      44              : 
      45              : /// `pageserver.toml`
      46              : ///
      47              : /// We use serde derive with `#[serde(default)]` to generate a deserializer
      48              : /// that fills in the default values for each config field.
      49              : ///
      50              : /// If there cannot be a static default value because we need to make runtime
      51              : /// checks to determine the default, make it an `Option` (which defaults to None).
      52              : /// The runtime check should be done in the consuming crate, i.e., `pageserver`.
      53              : #[serde_as]
      54           20 : #[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
      55              : #[serde(default, deny_unknown_fields)]
      56              : pub struct ConfigToml {
      57              :     // types mapped 1:1 into the runtime PageServerConfig type
      58              :     pub listen_pg_addr: String,
      59              :     pub listen_http_addr: String,
      60              :     pub availability_zone: Option<String>,
      61              :     #[serde(with = "humantime_serde")]
      62              :     pub wait_lsn_timeout: Duration,
      63              :     #[serde(with = "humantime_serde")]
      64              :     pub wal_redo_timeout: Duration,
      65              :     pub superuser: String,
      66              :     pub locale: String,
      67              :     pub page_cache_size: usize,
      68              :     pub max_file_descriptors: usize,
      69              :     pub pg_distrib_dir: Option<Utf8PathBuf>,
      70              :     #[serde_as(as = "serde_with::DisplayFromStr")]
      71              :     pub http_auth_type: AuthType,
      72              :     #[serde_as(as = "serde_with::DisplayFromStr")]
      73              :     pub pg_auth_type: AuthType,
      74              :     pub auth_validation_public_key_path: Option<Utf8PathBuf>,
      75              :     pub remote_storage: Option<RemoteStorageConfig>,
      76              :     pub tenant_config: TenantConfigToml,
      77              :     #[serde_as(as = "serde_with::DisplayFromStr")]
      78              :     pub broker_endpoint: storage_broker::Uri,
      79              :     #[serde(with = "humantime_serde")]
      80              :     pub broker_keepalive_interval: Duration,
      81              :     #[serde_as(as = "serde_with::DisplayFromStr")]
      82              :     pub log_format: LogFormat,
      83              :     pub concurrent_tenant_warmup: NonZeroUsize,
      84              :     pub concurrent_tenant_size_logical_size_queries: NonZeroUsize,
      85              :     #[serde(with = "humantime_serde")]
      86              :     pub metric_collection_interval: Duration,
      87              :     pub metric_collection_endpoint: Option<reqwest::Url>,
      88              :     pub metric_collection_bucket: Option<RemoteStorageConfig>,
      89              :     #[serde(with = "humantime_serde")]
      90              :     pub synthetic_size_calculation_interval: Duration,
      91              :     pub disk_usage_based_eviction: Option<DiskUsageEvictionTaskConfig>,
      92              :     pub test_remote_failures: u64,
      93              :     pub ondemand_download_behavior_treat_error_as_warn: bool,
      94              :     #[serde(with = "humantime_serde")]
      95              :     pub background_task_maximum_delay: Duration,
      96              :     pub control_plane_api: Option<reqwest::Url>,
      97              :     pub control_plane_api_token: Option<String>,
      98              :     pub control_plane_emergency_mode: bool,
      99              :     /// Unstable feature: subject to change or removal without notice.
     100              :     /// See <https://github.com/neondatabase/neon/pull/9218>.
     101              :     pub import_pgdata_upcall_api: Option<reqwest::Url>,
     102              :     /// Unstable feature: subject to change or removal without notice.
     103              :     /// See <https://github.com/neondatabase/neon/pull/9218>.
     104              :     pub import_pgdata_upcall_api_token: Option<String>,
     105              :     /// Unstable feature: subject to change or removal without notice.
     106              :     /// See <https://github.com/neondatabase/neon/pull/9218>.
     107              :     pub import_pgdata_aws_endpoint_url: Option<reqwest::Url>,
     108              :     pub heatmap_upload_concurrency: usize,
     109              :     pub secondary_download_concurrency: usize,
     110              :     pub virtual_file_io_engine: Option<crate::models::virtual_file::IoEngineKind>,
     111              :     pub ingest_batch_size: u64,
     112              :     pub max_vectored_read_bytes: MaxVectoredReadBytes,
     113              :     pub image_compression: ImageCompressionAlgorithm,
     114              :     pub timeline_offloading: bool,
     115              :     pub ephemeral_bytes_per_memory_kb: usize,
     116              :     pub l0_flush: Option<crate::models::L0FlushConfig>,
     117              :     pub virtual_file_io_mode: Option<crate::models::virtual_file::IoMode>,
     118              :     #[serde(skip_serializing_if = "Option::is_none")]
     119              :     pub no_sync: Option<bool>,
     120              :     pub wal_receiver_protocol: PostgresClientProtocol,
     121              :     pub page_service_pipelining: PageServicePipeliningConfig,
     122              :     pub get_vectored_concurrent_io: GetVectoredConcurrentIo,
     123              :     pub enable_read_path_debugging: Option<bool>,
     124              :     #[serde(skip_serializing_if = "Option::is_none")]
     125              :     pub validate_wal_contiguity: Option<bool>,
     126              : }
     127              : 
     128            4 : #[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
     129              : #[serde(deny_unknown_fields)]
     130              : pub struct DiskUsageEvictionTaskConfig {
     131              :     pub max_usage_pct: utils::serde_percent::Percent,
     132              :     pub min_avail_bytes: u64,
     133              :     #[serde(with = "humantime_serde")]
     134              :     pub period: Duration,
     135              :     #[cfg(feature = "testing")]
     136              :     pub mock_statvfs: Option<statvfs::mock::Behavior>,
     137              :     /// Select sorting for evicted layers
     138              :     #[serde(default)]
     139              :     pub eviction_order: EvictionOrder,
     140              : }
     141              : 
     142            0 : #[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
     143              : #[serde(tag = "mode", rename_all = "kebab-case")]
     144              : #[serde(deny_unknown_fields)]
     145              : pub enum PageServicePipeliningConfig {
     146              :     Serial,
     147              :     Pipelined(PageServicePipeliningConfigPipelined),
     148              : }
     149            0 : #[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
     150              : #[serde(deny_unknown_fields)]
     151              : pub struct PageServicePipeliningConfigPipelined {
     152              :     /// Causes runtime errors if larger than max get_vectored batch size.
     153              :     pub max_batch_size: NonZeroUsize,
     154              :     pub execution: PageServiceProtocolPipelinedExecutionStrategy,
     155              : }
     156              : 
     157            0 : #[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
     158              : #[serde(rename_all = "kebab-case")]
     159              : pub enum PageServiceProtocolPipelinedExecutionStrategy {
     160              :     ConcurrentFutures,
     161              :     Tasks,
     162              : }
     163              : 
     164            0 : #[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
     165              : #[serde(tag = "mode", rename_all = "kebab-case")]
     166              : #[serde(deny_unknown_fields)]
     167              : pub enum GetVectoredConcurrentIo {
     168              :     /// The read path is fully sequential: layers are visited
     169              :     /// one after the other and IOs are issued and waited upon
     170              :     /// from the same task that traverses the layers.
     171              :     Sequential,
     172              :     /// The read path still traverses layers sequentially, and
     173              :     /// index blocks will be read into the PS PageCache from
     174              :     /// that task, with waiting.
     175              :     /// But data IOs are dispatched and waited upon from a sidecar
     176              :     /// task so that the traversing task can continue to traverse
     177              :     /// layers while the IOs are in flight.
     178              :     /// If the PS PageCache miss rate is low, this improves
     179              :     /// throughput dramatically.
     180              :     SidecarTask,
     181              : }
     182              : 
     183              : pub mod statvfs {
     184              :     pub mod mock {
     185            0 :         #[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
     186              :         #[serde(tag = "type")]
     187              :         pub enum Behavior {
     188              :             Success {
     189              :                 blocksize: u64,
     190              :                 total_blocks: u64,
     191              :                 name_filter: Option<utils::serde_regex::Regex>,
     192              :             },
     193              :             #[cfg(feature = "testing")]
     194              :             Failure { mocked_error: MockedError },
     195              :         }
     196              : 
     197              :         #[cfg(feature = "testing")]
     198            0 :         #[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
     199              :         #[allow(clippy::upper_case_acronyms)]
     200              :         pub enum MockedError {
     201              :             EIO,
     202              :         }
     203              : 
     204              :         #[cfg(feature = "testing")]
     205              :         impl From<MockedError> for nix::Error {
     206            0 :             fn from(e: MockedError) -> Self {
     207            0 :                 match e {
     208            0 :                     MockedError::EIO => nix::Error::EIO,
     209            0 :                 }
     210            0 :             }
     211              :         }
     212              :     }
     213              : }
     214              : 
     215            0 : #[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
     216              : #[serde(tag = "type", content = "args")]
     217              : pub enum EvictionOrder {
     218              :     RelativeAccessed {
     219              :         highest_layer_count_loses_first: bool,
     220              :     },
     221              : }
     222              : 
     223              : impl Default for EvictionOrder {
     224            4 :     fn default() -> Self {
     225            4 :         Self::RelativeAccessed {
     226            4 :             highest_layer_count_loses_first: true,
     227            4 :         }
     228            4 :     }
     229              : }
     230              : 
     231            0 : #[derive(Copy, Clone, Debug, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
     232              : #[serde(transparent)]
     233              : pub struct MaxVectoredReadBytes(pub NonZeroUsize);
     234              : 
     235              : /// A tenant's calcuated configuration, which is the result of merging a
     236              : /// tenant's TenantConfOpt with the global TenantConf from PageServerConf.
     237              : ///
     238              : /// For storing and transmitting individual tenant's configuration, see
     239              : /// TenantConfOpt.
     240            4 : #[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
     241              : #[serde(deny_unknown_fields, default)]
     242              : pub struct TenantConfigToml {
     243              :     // Flush out an inmemory layer, if it's holding WAL older than this
     244              :     // This puts a backstop on how much WAL needs to be re-digested if the
     245              :     // page server crashes.
     246              :     // This parameter actually determines L0 layer file size.
     247              :     pub checkpoint_distance: u64,
     248              :     // Inmemory layer is also flushed at least once in checkpoint_timeout to
     249              :     // eventually upload WAL after activity is stopped.
     250              :     #[serde(with = "humantime_serde")]
     251              :     pub checkpoint_timeout: Duration,
     252              :     // Target file size, when creating image and delta layers.
     253              :     // This parameter determines L1 layer file size.
     254              :     pub compaction_target_size: u64,
     255              :     // How often to check if there's compaction work to be done.
     256              :     // Duration::ZERO means automatic compaction is disabled.
     257              :     #[serde(with = "humantime_serde")]
     258              :     pub compaction_period: Duration,
     259              :     /// Level0 delta layer threshold for compaction.
     260              :     pub compaction_threshold: usize,
     261              :     /// Controls the amount of L0 included in a single compaction iteration.
     262              :     /// The unit is `checkpoint_distance`, i.e., a size.
     263              :     /// We add L0s to the set of layers to compact until their cumulative
     264              :     /// size exceeds `compaction_upper_limit * checkpoint_distance`.
     265              :     pub compaction_upper_limit: usize,
     266              :     pub compaction_algorithm: crate::models::CompactionAlgorithmSettings,
     267              :     /// If true, compact down L0 across all tenant timelines before doing regular compaction.
     268              :     pub compaction_l0_first: bool,
     269              :     /// If true, use a separate semaphore (i.e. concurrency limit) for the L0 compaction pass. Only
     270              :     /// has an effect if `compaction_l0_first` is `true`.
     271              :     pub compaction_l0_semaphore: bool,
     272              :     /// Level0 delta layer threshold at which to delay layer flushes for compaction backpressure,
     273              :     /// such that they take 2x as long, and start waiting for layer flushes during ephemeral layer
     274              :     /// rolls. This helps compaction keep up with WAL ingestion, and avoids read amplification
     275              :     /// blowing up. Should be >compaction_threshold. 0 to disable. Disabled by default.
     276              :     pub l0_flush_delay_threshold: Option<usize>,
     277              :     /// Level0 delta layer threshold at which to stall layer flushes. Must be >compaction_threshold
     278              :     /// to avoid deadlock. 0 to disable. Disabled by default.
     279              :     pub l0_flush_stall_threshold: Option<usize>,
     280              :     /// If true, Level0 delta layer flushes will wait for S3 upload before flushing the next
     281              :     /// layer. This is a temporary backpressure mechanism which should be removed once
     282              :     /// l0_flush_{delay,stall}_threshold is fully enabled.
     283              :     pub l0_flush_wait_upload: bool,
     284              :     // Determines how much history is retained, to allow
     285              :     // branching and read replicas at an older point in time.
     286              :     // The unit is #of bytes of WAL.
     287              :     // Page versions older than this are garbage collected away.
     288              :     pub gc_horizon: u64,
     289              :     // Interval at which garbage collection is triggered.
     290              :     // Duration::ZERO means automatic GC is disabled
     291              :     #[serde(with = "humantime_serde")]
     292              :     pub gc_period: Duration,
     293              :     // Delta layer churn threshold to create L1 image layers.
     294              :     pub image_creation_threshold: usize,
     295              :     // Determines how much history is retained, to allow
     296              :     // branching and read replicas at an older point in time.
     297              :     // The unit is time.
     298              :     // Page versions older than this are garbage collected away.
     299              :     #[serde(with = "humantime_serde")]
     300              :     pub pitr_interval: Duration,
     301              :     /// Maximum amount of time to wait while opening a connection to receive wal, before erroring.
     302              :     #[serde(with = "humantime_serde")]
     303              :     pub walreceiver_connect_timeout: Duration,
     304              :     /// Considers safekeepers stalled after no WAL updates were received longer than this threshold.
     305              :     /// A stalled safekeeper will be changed to a newer one when it appears.
     306              :     #[serde(with = "humantime_serde")]
     307              :     pub lagging_wal_timeout: Duration,
     308              :     /// Considers safekeepers lagging when their WAL is behind another safekeeper for more than this threshold.
     309              :     /// A lagging safekeeper will be changed after `lagging_wal_timeout` time elapses since the last WAL update,
     310              :     /// to avoid eager reconnects.
     311              :     pub max_lsn_wal_lag: NonZeroU64,
     312              :     pub eviction_policy: crate::models::EvictionPolicy,
     313              :     pub min_resident_size_override: Option<u64>,
     314              :     // See the corresponding metric's help string.
     315              :     #[serde(with = "humantime_serde")]
     316              :     pub evictions_low_residence_duration_metric_threshold: Duration,
     317              : 
     318              :     /// If non-zero, the period between uploads of a heatmap from attached tenants.  This
     319              :     /// may be disabled if a Tenant will not have secondary locations: only secondary
     320              :     /// locations will use the heatmap uploaded by attached locations.
     321              :     #[serde(with = "humantime_serde")]
     322              :     pub heatmap_period: Duration,
     323              : 
     324              :     /// If true then SLRU segments are dowloaded on demand, if false SLRU segments are included in basebackup
     325              :     pub lazy_slru_download: bool,
     326              : 
     327              :     pub timeline_get_throttle: crate::models::ThrottleConfig,
     328              : 
     329              :     // How much WAL must be ingested before checking again whether a new image layer is required.
     330              :     // Expresed in multiples of checkpoint distance.
     331              :     pub image_layer_creation_check_threshold: u8,
     332              : 
     333              :     // How many multiples of L0 `compaction_threshold` will preempt image layer creation and do L0 compaction.
     334              :     // Set to 0 to disable preemption.
     335              :     pub image_creation_preempt_threshold: usize,
     336              : 
     337              :     /// The length for an explicit LSN lease request.
     338              :     /// Layers needed to reconstruct pages at LSN will not be GC-ed during this interval.
     339              :     #[serde(with = "humantime_serde")]
     340              :     pub lsn_lease_length: Duration,
     341              : 
     342              :     /// The length for an implicit LSN lease granted as part of `get_lsn_by_timestamp` request.
     343              :     /// Layers needed to reconstruct pages at LSN will not be GC-ed during this interval.
     344              :     #[serde(with = "humantime_serde")]
     345              :     pub lsn_lease_length_for_ts: Duration,
     346              : 
     347              :     /// Enable auto-offloading of timelines.
     348              :     /// (either this flag or the pageserver-global one need to be set)
     349              :     pub timeline_offloading: bool,
     350              : 
     351              :     pub wal_receiver_protocol_override: Option<PostgresClientProtocol>,
     352              : 
     353              :     /// Enable rel_size_v2 for this tenant. Once enabled, the tenant will persist this information into
     354              :     /// `index_part.json`, and it cannot be reversed.
     355              :     pub rel_size_v2_enabled: bool,
     356              : 
     357              :     // gc-compaction related configs
     358              :     /// Enable automatic gc-compaction trigger on this tenant.
     359              :     pub gc_compaction_enabled: bool,
     360              :     /// The initial threshold for gc-compaction in KB. Once the total size of layers below the gc-horizon is above this threshold,
     361              :     /// gc-compaction will be triggered.
     362              :     pub gc_compaction_initial_threshold_kb: u64,
     363              :     /// The ratio that triggers the auto gc-compaction. If (the total size of layers between L2 LSN and gc-horizon) / (size below the L2 LSN)
     364              :     /// is above this ratio, gc-compaction will be triggered.
     365              :     pub gc_compaction_ratio_percent: u64,
     366              : }
     367              : 
     368              : pub mod defaults {
     369              :     pub use storage_broker::DEFAULT_ENDPOINT as BROKER_DEFAULT_ENDPOINT;
     370              : 
     371              :     use crate::models::ImageCompressionAlgorithm;
     372              : 
     373              :     pub const DEFAULT_WAIT_LSN_TIMEOUT: &str = "300 s";
     374              :     pub const DEFAULT_WAL_REDO_TIMEOUT: &str = "60 s";
     375              : 
     376              :     pub const DEFAULT_SUPERUSER: &str = "cloud_admin";
     377              :     pub const DEFAULT_LOCALE: &str = if cfg!(target_os = "macos") {
     378              :         "C"
     379              :     } else {
     380              :         "C.UTF-8"
     381              :     };
     382              : 
     383              :     pub const DEFAULT_PAGE_CACHE_SIZE: usize = 8192;
     384              :     pub const DEFAULT_MAX_FILE_DESCRIPTORS: usize = 100;
     385              : 
     386              :     pub const DEFAULT_LOG_FORMAT: &str = "plain";
     387              : 
     388              :     pub const DEFAULT_CONCURRENT_TENANT_WARMUP: usize = 8;
     389              : 
     390              :     pub const DEFAULT_CONCURRENT_TENANT_SIZE_LOGICAL_SIZE_QUERIES: usize = 1;
     391              : 
     392              :     pub const DEFAULT_METRIC_COLLECTION_INTERVAL: &str = "10 min";
     393              :     pub const DEFAULT_METRIC_COLLECTION_ENDPOINT: Option<reqwest::Url> = None;
     394              :     pub const DEFAULT_SYNTHETIC_SIZE_CALCULATION_INTERVAL: &str = "10 min";
     395              :     pub const DEFAULT_BACKGROUND_TASK_MAXIMUM_DELAY: &str = "10s";
     396              : 
     397              :     pub const DEFAULT_HEATMAP_UPLOAD_CONCURRENCY: usize = 8;
     398              :     pub const DEFAULT_SECONDARY_DOWNLOAD_CONCURRENCY: usize = 1;
     399              : 
     400              :     pub const DEFAULT_INGEST_BATCH_SIZE: u64 = 100;
     401              : 
     402              :     /// Soft limit for the maximum size of a vectored read.
     403              :     ///
     404              :     /// This is determined by the largest NeonWalRecord that can exist (minus dbdir and reldir keys
     405              :     /// which are bounded by the blob io limits only). As of this writing, that is a `NeonWalRecord::ClogSetCommitted` record,
     406              :     /// with 32k xids. That's the max number of XIDS on a single CLOG page. The size of such a record
     407              :     /// is `sizeof(Transactionid) * 32768 + (some fixed overhead from 'timestamp`, the Vec length and whatever extra serde serialization adds)`.
     408              :     /// That is, slightly above 128 kB.
     409              :     pub const DEFAULT_MAX_VECTORED_READ_BYTES: usize = 130 * 1024; // 130 KiB
     410              : 
     411              :     pub const DEFAULT_IMAGE_COMPRESSION: ImageCompressionAlgorithm =
     412              :         ImageCompressionAlgorithm::Zstd { level: Some(1) };
     413              : 
     414              :     pub const DEFAULT_EPHEMERAL_BYTES_PER_MEMORY_KB: usize = 0;
     415              : 
     416              :     pub const DEFAULT_IO_BUFFER_ALIGNMENT: usize = 512;
     417              : 
     418              :     pub const DEFAULT_WAL_RECEIVER_PROTOCOL: utils::postgres_client::PostgresClientProtocol =
     419              :         utils::postgres_client::PostgresClientProtocol::Vanilla;
     420              : }
     421              : 
     422              : impl Default for ConfigToml {
     423          488 :     fn default() -> Self {
     424              :         use defaults::*;
     425              : 
     426              :         Self {
     427          488 :             listen_pg_addr: (DEFAULT_PG_LISTEN_ADDR.to_string()),
     428          488 :             listen_http_addr: (DEFAULT_HTTP_LISTEN_ADDR.to_string()),
     429          488 :             availability_zone: (None),
     430          488 :             wait_lsn_timeout: (humantime::parse_duration(DEFAULT_WAIT_LSN_TIMEOUT)
     431          488 :                 .expect("cannot parse default wait lsn timeout")),
     432          488 :             wal_redo_timeout: (humantime::parse_duration(DEFAULT_WAL_REDO_TIMEOUT)
     433          488 :                 .expect("cannot parse default wal redo timeout")),
     434          488 :             superuser: (DEFAULT_SUPERUSER.to_string()),
     435          488 :             locale: DEFAULT_LOCALE.to_string(),
     436          488 :             page_cache_size: (DEFAULT_PAGE_CACHE_SIZE),
     437          488 :             max_file_descriptors: (DEFAULT_MAX_FILE_DESCRIPTORS),
     438          488 :             pg_distrib_dir: None, // Utf8PathBuf::from("./pg_install"), // TODO: formely, this was std::env::current_dir()
     439          488 :             http_auth_type: (AuthType::Trust),
     440          488 :             pg_auth_type: (AuthType::Trust),
     441          488 :             auth_validation_public_key_path: (None),
     442          488 :             remote_storage: None,
     443          488 :             broker_endpoint: (storage_broker::DEFAULT_ENDPOINT
     444          488 :                 .parse()
     445          488 :                 .expect("failed to parse default broker endpoint")),
     446          488 :             broker_keepalive_interval: (humantime::parse_duration(
     447          488 :                 storage_broker::DEFAULT_KEEPALIVE_INTERVAL,
     448          488 :             )
     449          488 :             .expect("cannot parse default keepalive interval")),
     450          488 :             log_format: (LogFormat::from_str(DEFAULT_LOG_FORMAT).unwrap()),
     451          488 : 
     452          488 :             concurrent_tenant_warmup: (NonZeroUsize::new(DEFAULT_CONCURRENT_TENANT_WARMUP)
     453          488 :                 .expect("Invalid default constant")),
     454          488 :             concurrent_tenant_size_logical_size_queries: NonZeroUsize::new(
     455          488 :                 DEFAULT_CONCURRENT_TENANT_SIZE_LOGICAL_SIZE_QUERIES,
     456          488 :             )
     457          488 :             .unwrap(),
     458          488 :             metric_collection_interval: (humantime::parse_duration(
     459          488 :                 DEFAULT_METRIC_COLLECTION_INTERVAL,
     460          488 :             )
     461          488 :             .expect("cannot parse default metric collection interval")),
     462          488 :             synthetic_size_calculation_interval: (humantime::parse_duration(
     463          488 :                 DEFAULT_SYNTHETIC_SIZE_CALCULATION_INTERVAL,
     464          488 :             )
     465          488 :             .expect("cannot parse default synthetic size calculation interval")),
     466          488 :             metric_collection_endpoint: (DEFAULT_METRIC_COLLECTION_ENDPOINT),
     467          488 : 
     468          488 :             metric_collection_bucket: (None),
     469          488 : 
     470          488 :             disk_usage_based_eviction: (None),
     471          488 : 
     472          488 :             test_remote_failures: (0),
     473          488 : 
     474          488 :             ondemand_download_behavior_treat_error_as_warn: (false),
     475          488 : 
     476          488 :             background_task_maximum_delay: (humantime::parse_duration(
     477          488 :                 DEFAULT_BACKGROUND_TASK_MAXIMUM_DELAY,
     478          488 :             )
     479          488 :             .unwrap()),
     480          488 : 
     481          488 :             control_plane_api: (None),
     482          488 :             control_plane_api_token: (None),
     483          488 :             control_plane_emergency_mode: (false),
     484          488 : 
     485          488 :             import_pgdata_upcall_api: (None),
     486          488 :             import_pgdata_upcall_api_token: (None),
     487          488 :             import_pgdata_aws_endpoint_url: (None),
     488          488 : 
     489          488 :             heatmap_upload_concurrency: (DEFAULT_HEATMAP_UPLOAD_CONCURRENCY),
     490          488 :             secondary_download_concurrency: (DEFAULT_SECONDARY_DOWNLOAD_CONCURRENCY),
     491          488 : 
     492          488 :             ingest_batch_size: (DEFAULT_INGEST_BATCH_SIZE),
     493          488 : 
     494          488 :             virtual_file_io_engine: None,
     495          488 : 
     496          488 :             max_vectored_read_bytes: (MaxVectoredReadBytes(
     497          488 :                 NonZeroUsize::new(DEFAULT_MAX_VECTORED_READ_BYTES).unwrap(),
     498          488 :             )),
     499          488 :             image_compression: (DEFAULT_IMAGE_COMPRESSION),
     500          488 :             timeline_offloading: true,
     501          488 :             ephemeral_bytes_per_memory_kb: (DEFAULT_EPHEMERAL_BYTES_PER_MEMORY_KB),
     502          488 :             l0_flush: None,
     503          488 :             virtual_file_io_mode: None,
     504          488 :             tenant_config: TenantConfigToml::default(),
     505          488 :             no_sync: None,
     506          488 :             wal_receiver_protocol: DEFAULT_WAL_RECEIVER_PROTOCOL,
     507          488 :             page_service_pipelining: if !cfg!(test) {
     508          488 :                 PageServicePipeliningConfig::Serial
     509              :             } else {
     510            0 :                 PageServicePipeliningConfig::Pipelined(PageServicePipeliningConfigPipelined {
     511            0 :                     max_batch_size: NonZeroUsize::new(32).unwrap(),
     512            0 :                     execution: PageServiceProtocolPipelinedExecutionStrategy::ConcurrentFutures,
     513            0 :                 })
     514              :             },
     515          488 :             get_vectored_concurrent_io: if !cfg!(test) {
     516          488 :                 GetVectoredConcurrentIo::Sequential
     517              :             } else {
     518            0 :                 GetVectoredConcurrentIo::SidecarTask
     519              :             },
     520          488 :             enable_read_path_debugging: if cfg!(test) || cfg!(feature = "testing") {
     521          488 :                 Some(true)
     522              :             } else {
     523            0 :                 None
     524              :             },
     525          488 :             validate_wal_contiguity: None,
     526          488 :         }
     527          488 :     }
     528              : }
     529              : 
     530              : pub mod tenant_conf_defaults {
     531              : 
     532              :     // FIXME: This current value is very low. I would imagine something like 1 GB or 10 GB
     533              :     // would be more appropriate. But a low value forces the code to be exercised more,
     534              :     // which is good for now to trigger bugs.
     535              :     // This parameter actually determines L0 layer file size.
     536              :     pub const DEFAULT_CHECKPOINT_DISTANCE: u64 = 256 * 1024 * 1024;
     537              :     pub const DEFAULT_CHECKPOINT_TIMEOUT: &str = "10 m";
     538              : 
     539              :     // FIXME the below configs are only used by legacy algorithm. The new algorithm
     540              :     // has different parameters.
     541              : 
     542              :     // Target file size, when creating image and delta layers.
     543              :     // This parameter determines L1 layer file size.
     544              :     pub const DEFAULT_COMPACTION_TARGET_SIZE: u64 = 128 * 1024 * 1024;
     545              : 
     546              :     pub const DEFAULT_COMPACTION_PERIOD: &str = "20 s";
     547              :     pub const DEFAULT_COMPACTION_THRESHOLD: usize = 10;
     548              : 
     549              :     // This value needs to be tuned to avoid OOM. We have 3/4*CPUs threads for L0 compaction, that's
     550              :     // 3/4*16=9 on most of our pageservers. Compacting 20 layers requires about 1 GB memory (could
     551              :     // be reduced later by optimizing L0 hole calculation to avoid loading all keys into memory). So
     552              :     // with this config, we can get a maximum peak compaction usage of 9 GB.
     553              :     pub const DEFAULT_COMPACTION_UPPER_LIMIT: usize = 20;
     554              :     pub const DEFAULT_COMPACTION_L0_FIRST: bool = false;
     555              :     pub const DEFAULT_COMPACTION_L0_SEMAPHORE: bool = true;
     556              : 
     557              :     pub const DEFAULT_COMPACTION_ALGORITHM: crate::models::CompactionAlgorithm =
     558              :         crate::models::CompactionAlgorithm::Legacy;
     559              : 
     560              :     pub const DEFAULT_L0_FLUSH_WAIT_UPLOAD: bool = true;
     561              : 
     562              :     pub const DEFAULT_GC_HORIZON: u64 = 64 * 1024 * 1024;
     563              : 
     564              :     // Large DEFAULT_GC_PERIOD is fine as long as PITR_INTERVAL is larger.
     565              :     // If there's a need to decrease this value, first make sure that GC
     566              :     // doesn't hold a layer map write lock for non-trivial operations.
     567              :     // Relevant: https://github.com/neondatabase/neon/issues/3394
     568              :     pub const DEFAULT_GC_PERIOD: &str = "1 hr";
     569              :     pub const DEFAULT_IMAGE_CREATION_THRESHOLD: usize = 3;
     570              :     // If there are more than threshold * compaction_threshold (that is 3 * 10 in the default config) L0 layers, image
     571              :     // layer creation will end immediately. Set to 0 to disable. The target default will be 3 once we
     572              :     // want to enable this feature.
     573              :     pub const DEFAULT_IMAGE_CREATION_PREEMPT_THRESHOLD: usize = 0;
     574              :     pub const DEFAULT_PITR_INTERVAL: &str = "7 days";
     575              :     pub const DEFAULT_WALRECEIVER_CONNECT_TIMEOUT: &str = "10 seconds";
     576              :     pub const DEFAULT_WALRECEIVER_LAGGING_WAL_TIMEOUT: &str = "10 seconds";
     577              :     // The default limit on WAL lag should be set to avoid causing disconnects under high throughput
     578              :     // scenarios: since the broker stats are updated ~1/s, a value of 1GiB should be sufficient for
     579              :     // throughputs up to 1GiB/s per timeline.
     580              :     pub const DEFAULT_MAX_WALRECEIVER_LSN_WAL_LAG: u64 = 1024 * 1024 * 1024;
     581              :     pub const DEFAULT_EVICTIONS_LOW_RESIDENCE_DURATION_METRIC_THRESHOLD: &str = "24 hour";
     582              :     // By default ingest enough WAL for two new L0 layers before checking if new image
     583              :     // image layers should be created.
     584              :     pub const DEFAULT_IMAGE_LAYER_CREATION_CHECK_THRESHOLD: u8 = 2;
     585              :     pub const DEFAULT_GC_COMPACTION_ENABLED: bool = false;
     586              :     pub const DEFAULT_GC_COMPACTION_INITIAL_THRESHOLD_KB: u64 = 5 * 1024 * 1024; // 5GB
     587              :     pub const DEFAULT_GC_COMPACTION_RATIO_PERCENT: u64 = 100;
     588              : }
     589              : 
     590              : impl Default for TenantConfigToml {
     591          924 :     fn default() -> Self {
     592              :         use tenant_conf_defaults::*;
     593          924 :         Self {
     594          924 :             checkpoint_distance: DEFAULT_CHECKPOINT_DISTANCE,
     595          924 :             checkpoint_timeout: humantime::parse_duration(DEFAULT_CHECKPOINT_TIMEOUT)
     596          924 :                 .expect("cannot parse default checkpoint timeout"),
     597          924 :             compaction_target_size: DEFAULT_COMPACTION_TARGET_SIZE,
     598          924 :             compaction_period: humantime::parse_duration(DEFAULT_COMPACTION_PERIOD)
     599          924 :                 .expect("cannot parse default compaction period"),
     600          924 :             compaction_threshold: DEFAULT_COMPACTION_THRESHOLD,
     601          924 :             compaction_upper_limit: DEFAULT_COMPACTION_UPPER_LIMIT,
     602          924 :             compaction_algorithm: crate::models::CompactionAlgorithmSettings {
     603          924 :                 kind: DEFAULT_COMPACTION_ALGORITHM,
     604          924 :             },
     605          924 :             compaction_l0_first: DEFAULT_COMPACTION_L0_FIRST,
     606          924 :             compaction_l0_semaphore: DEFAULT_COMPACTION_L0_SEMAPHORE,
     607          924 :             l0_flush_delay_threshold: None,
     608          924 :             l0_flush_stall_threshold: None,
     609          924 :             l0_flush_wait_upload: DEFAULT_L0_FLUSH_WAIT_UPLOAD,
     610          924 :             gc_horizon: DEFAULT_GC_HORIZON,
     611          924 :             gc_period: humantime::parse_duration(DEFAULT_GC_PERIOD)
     612          924 :                 .expect("cannot parse default gc period"),
     613          924 :             image_creation_threshold: DEFAULT_IMAGE_CREATION_THRESHOLD,
     614          924 :             pitr_interval: humantime::parse_duration(DEFAULT_PITR_INTERVAL)
     615          924 :                 .expect("cannot parse default PITR interval"),
     616          924 :             walreceiver_connect_timeout: humantime::parse_duration(
     617          924 :                 DEFAULT_WALRECEIVER_CONNECT_TIMEOUT,
     618          924 :             )
     619          924 :             .expect("cannot parse default walreceiver connect timeout"),
     620          924 :             lagging_wal_timeout: humantime::parse_duration(DEFAULT_WALRECEIVER_LAGGING_WAL_TIMEOUT)
     621          924 :                 .expect("cannot parse default walreceiver lagging wal timeout"),
     622          924 :             max_lsn_wal_lag: NonZeroU64::new(DEFAULT_MAX_WALRECEIVER_LSN_WAL_LAG)
     623          924 :                 .expect("cannot parse default max walreceiver Lsn wal lag"),
     624          924 :             eviction_policy: crate::models::EvictionPolicy::NoEviction,
     625          924 :             min_resident_size_override: None,
     626          924 :             evictions_low_residence_duration_metric_threshold: humantime::parse_duration(
     627          924 :                 DEFAULT_EVICTIONS_LOW_RESIDENCE_DURATION_METRIC_THRESHOLD,
     628          924 :             )
     629          924 :             .expect("cannot parse default evictions_low_residence_duration_metric_threshold"),
     630          924 :             heatmap_period: Duration::ZERO,
     631          924 :             lazy_slru_download: false,
     632          924 :             timeline_get_throttle: crate::models::ThrottleConfig::disabled(),
     633          924 :             image_layer_creation_check_threshold: DEFAULT_IMAGE_LAYER_CREATION_CHECK_THRESHOLD,
     634          924 :             image_creation_preempt_threshold: DEFAULT_IMAGE_CREATION_PREEMPT_THRESHOLD,
     635          924 :             lsn_lease_length: LsnLease::DEFAULT_LENGTH,
     636          924 :             lsn_lease_length_for_ts: LsnLease::DEFAULT_LENGTH_FOR_TS,
     637          924 :             timeline_offloading: true,
     638          924 :             wal_receiver_protocol_override: None,
     639          924 :             rel_size_v2_enabled: false,
     640          924 :             gc_compaction_enabled: DEFAULT_GC_COMPACTION_ENABLED,
     641          924 :             gc_compaction_initial_threshold_kb: DEFAULT_GC_COMPACTION_INITIAL_THRESHOLD_KB,
     642          924 :             gc_compaction_ratio_percent: DEFAULT_GC_COMPACTION_RATIO_PERCENT,
     643          924 :         }
     644          924 :     }
     645              : }
        

Generated by: LCOV version 2.1-beta