mirror of
https://github.com/neondatabase/neon.git
synced 2026-06-05 06:20:37 +00:00
pageserver: default to 4MiB stack size and add env var to control it (#8862)
# Motivation In https://github.com/neondatabase/neon/pull/8832 I get tokio runtime worker stack overflow errors in debug builds. In a similar vein, I had tokio runtimer worker stack overflow when trying to eliminate `async_trait` (https://github.com/neondatabase/neon/pull/8296). The 2MiB default is kind of arbitrary - so this PR bumps it to 4MiB. It also adds an env var to control it. # Risk Assessment With our 4 runtimes, the worst case stack memory usage is `4 (runtimes) * ($num_cpus (executor threads) + 512 (blocking pool threads)) * 4MiB`. On i3en.3xlarge, that's `8384 MiB`. On im4gn.2xlarge, that's `8320 MiB`. Before this change, it was half that. Looking at production metrics, we _do_ have the headroom to accomodate this worst case case. # Alternatives The problems only occur with debug builds, so technically we could only raise the stack size for debug builds. However, it would be another configuration where `debug != release`. # Future Work If we ever enable single runtime mode in prod (=> https://github.com/neondatabase/neon/issues/7312 ) then the worst case will drop to 25% of its current value. Eliminating the use of `tokio::spawn_blocking` / `tokio::fs` in favor of `tokio-epoll-uring` (=> https://github.com/neondatabase/neon/issues/7370 ) would reduce the worst case to `4 (runtimes) * $num_cpus (executor threads) * 4 MiB`.
This commit is contained in:
committed by
GitHub
parent
a644f01b6a
commit
c7481402a0
@@ -146,6 +146,12 @@ impl FromStr for TokioRuntimeMode {
|
||||
}
|
||||
}
|
||||
|
||||
static TOKIO_THREAD_STACK_SIZE: Lazy<NonZeroUsize> = Lazy::new(|| {
|
||||
env::var("NEON_PAGESERVER_TOKIO_THREAD_STACK_SIZE")
|
||||
// the default 2MiB are insufficent, especially in debug mode
|
||||
.unwrap_or_else(|| NonZeroUsize::new(4 * 1024 * 1024).unwrap())
|
||||
});
|
||||
|
||||
static ONE_RUNTIME: Lazy<Option<tokio::runtime::Runtime>> = Lazy::new(|| {
|
||||
let thread_name = "pageserver-tokio";
|
||||
let Some(mode) = env::var("NEON_PAGESERVER_USE_ONE_RUNTIME") else {
|
||||
@@ -164,6 +170,7 @@ static ONE_RUNTIME: Lazy<Option<tokio::runtime::Runtime>> = Lazy::new(|| {
|
||||
tokio::runtime::Builder::new_current_thread()
|
||||
.thread_name(thread_name)
|
||||
.enable_all()
|
||||
.thread_stack_size(TOKIO_THREAD_STACK_SIZE.get())
|
||||
.build()
|
||||
.expect("failed to create one single runtime")
|
||||
}
|
||||
@@ -173,6 +180,7 @@ static ONE_RUNTIME: Lazy<Option<tokio::runtime::Runtime>> = Lazy::new(|| {
|
||||
.thread_name(thread_name)
|
||||
.enable_all()
|
||||
.worker_threads(num_workers.get())
|
||||
.thread_stack_size(TOKIO_THREAD_STACK_SIZE.get())
|
||||
.build()
|
||||
.expect("failed to create one multi-threaded runtime")
|
||||
}
|
||||
@@ -199,6 +207,7 @@ macro_rules! pageserver_runtime {
|
||||
.thread_name($name)
|
||||
.worker_threads(TOKIO_WORKER_THREADS.get())
|
||||
.enable_all()
|
||||
.thread_stack_size(TOKIO_THREAD_STACK_SIZE.get())
|
||||
.build()
|
||||
.expect(std::concat!("Failed to create runtime ", $name))
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user